aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.travis.yml29
-rw-r--r--erts/doc/src/erlang.xml172
-rw-r--r--erts/doc/src/notes.xml15
-rw-r--r--erts/emulator/beam/erl_process.h2
-rw-r--r--erts/etc/unix/cerl.src21
-rw-r--r--erts/etc/unix/etp-commands.in26
-rw-r--r--erts/preloaded/src/erlang.erl3
-rw-r--r--lib/erl_interface/doc/src/notes.xml18
-rw-r--r--lib/erl_interface/src/connect/ei_connect.c9
-rw-r--r--lib/ftp/doc/src/ftp.xml8
-rw-r--r--lib/ftp/src/ftp.erl124
-rw-r--r--lib/inets/doc/src/notes.xml22
-rw-r--r--lib/kernel/doc/src/notes.xml20
-rw-r--r--lib/runtime_tools/src/observer_backend.erl2
-rw-r--r--lib/ssh/doc/src/notes.xml28
-rw-r--r--lib/ssh/doc/src/ssh_sftp.xml8
-rw-r--r--lib/ssh/src/ssh_sftp.erl13
-rw-r--r--lib/ssh/src/ssh_sftpd.erl6
-rw-r--r--lib/ssh/src/ssh_xfer.erl2
-rw-r--r--lib/ssh/vsn.mk1
-rw-r--r--lib/stdlib/src/beam_lib.erl23
-rw-r--r--lib/stdlib/src/erl_eval.erl15
-rw-r--r--lib/stdlib/src/erl_parse.yrl2
-rw-r--r--lib/stdlib/src/erl_pp.erl4
-rw-r--r--lib/stdlib/test/beam_lib_SUITE.erl32
-rw-r--r--lib/syntax_tools/doc/src/notes.xml19
-rw-r--r--lib/syntax_tools/src/erl_syntax.erl41
-rw-r--r--lib/syntax_tools/test/syntax_tools_SUITE.erl1
-rw-r--r--lib/tools/test/xref_SUITE.erl6
-rw-r--r--otp_versions.table2
-rwxr-xr-xscripts/build-otp34
-rwxr-xr-xscripts/pre-push37
-rw-r--r--system/doc/design_principles/statem.xml47
33 files changed, 502 insertions, 290 deletions
diff --git a/.travis.yml b/.travis.yml
index 174f259a7d..ee724f8947 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -49,19 +49,20 @@ matrix:
- env: Linux64Docbuild
script:
- ./scripts/build-otp docs
- ### Disabled for now, we do not want this to push to otp repo
- # deploy:
- # provider: pages
- # skip-cleanup: true
- # keep-history: true
- # verbose: true
- # github-token:
- # secure: oea4VBDok/gSPwo82XRkM3C5mpyVrcgJfOHgzO01rN4UbWN615wpnTLmkwe9gtkiSwRNNT6GoZ8Rx0EM5ByS2H3qY65bj3M+clMgFAPBn7aHDmnWpi8pi8OBIMmIGxHYQn0hzY4ZCVZQ1FtzTrLZDqZrAZBAGdgDdlH9IrsnBDUKNKzU28UMEgXJKX7bwdHo5H7JGkKeGh6bMi7/s5f/MwTQgp5Iv+PUhCZ1II+Wxz+fh+B6O8kgpq6oaBLjKeaim8bpeQ/vER6Vbaf6ORH0JiJcivDeBAfOVXyx75Omam3fqEuAGW1tmvXWljijWI21WhWmjZc+s8z5ML9wEBKlw0w9BGlzVs7Z+nVtAxufx0YqTsMhlzruxzhaNxh+7jEAMsU9LzBR3AHugqV5xbp3cyYEhWQl+MkhtrKsjs2MyZeyL2T9aeXJBDC6Jb2mznjvHKm11r5oz986uGr88qbDrwT+arRVYDFBvG52nqXa+4Hn+qPoZqDl4JC0YQeVhkbYtpPS1CYkl7JAXev2L4wDSc9Cywr02tJCTrR/yWKEANyYtVl2PzNkKAAvtROpEJv6y3PxhBJzr+Qk/MDLZWGV0KN4gNIYSxFkTFUddbgF53ZnVKAh4tv/vr7Uxvup9Zy7pqF9h+p4jZ0Yq0Y1AESCorU+qfXAxnGiKO8dewuBQhI=
- # on:
- # # We only deploy on pushes to branches
- # tags: false
- # condition: $TRAVIS_PULL_REQUEST = "false"
- # repo: erlang/otp
+ deploy:
+ provider: pages
+ repo: erlang/cd
+ target-branch: master
+ skip-cleanup: true
+ keep-history: true
+ verbose: true
+ github-token: $ERLANG_CD_GITHUB_TOKEN
+ on:
+ # We only deploy on pushes to branches
+ all_branches: true
+ tags: false
+ condition: $TRAVIS_PULL_REQUEST = "false"
+ repo: erlang/otp
# This stage publishes a otp bundle that contains multiple
# Erlang/OTP source repositories
- stage: deploy
@@ -73,7 +74,7 @@ matrix:
provider: releases
skip_cleanup: true
api_key:
- secure: oea4VBDok/gSPwo82XRkM3C5mpyVrcgJfOHgzO01rN4UbWN615wpnTLmkwe9gtkiSwRNNT6GoZ8Rx0EM5ByS2H3qY65bj3M+clMgFAPBn7aHDmnWpi8pi8OBIMmIGxHYQn0hzY4ZCVZQ1FtzTrLZDqZrAZBAGdgDdlH9IrsnBDUKNKzU28UMEgXJKX7bwdHo5H7JGkKeGh6bMi7/s5f/MwTQgp5Iv+PUhCZ1II+Wxz+fh+B6O8kgpq6oaBLjKeaim8bpeQ/vER6Vbaf6ORH0JiJcivDeBAfOVXyx75Omam3fqEuAGW1tmvXWljijWI21WhWmjZc+s8z5ML9wEBKlw0w9BGlzVs7Z+nVtAxufx0YqTsMhlzruxzhaNxh+7jEAMsU9LzBR3AHugqV5xbp3cyYEhWQl+MkhtrKsjs2MyZeyL2T9aeXJBDC6Jb2mznjvHKm11r5oz986uGr88qbDrwT+arRVYDFBvG52nqXa+4Hn+qPoZqDl4JC0YQeVhkbYtpPS1CYkl7JAXev2L4wDSc9Cywr02tJCTrR/yWKEANyYtVl2PzNkKAAvtROpEJv6y3PxhBJzr+Qk/MDLZWGV0KN4gNIYSxFkTFUddbgF53ZnVKAh4tv/vr7Uxvup9Zy7pqF9h+p4jZ0Yq0Y1AESCorU+qfXAxnGiKO8dewuBQhI=
+ secure: vW5PN6zng5H5+TCvwfwpGZsABrdCWYcFwDm3KXq+plsecBmTayu/0jgNso5Z97FbzDGVTLHWchvywEYQWnmrEByyOrqH73v1LN6JEfN99VpSrdFr15IzhblcyU1R9ugYc3WEoYjX0Q1uGelDSWRuuQOPbzy8mZf3D4rSGonyraP7jPTdHhs5P3ZWk6OMFz+tCdF4XohXqbhXIBOeH/EKg0svX2u5IcV01/YOL8LHWz6G7+gqBryEXx1+ngjQXQmMQwd7Yg3WOKE4XV9gX8ixZsbpUPZXAQKF+VOYdEgeiIr1hI0tBQUYX7FYEzYH5MCxqng5RdaPTOAm1oQroyGkIcWSXzDwN4AhJ7xqa/0NRdEaBPdQzPBCc+pVUDkxBR1ytXjBQqdQMnI6184TDiU5XBnj3kmieLkkKPKQNoPve/Y8Q8zutw4GNc7gixGcQCjtAFUbrT73QVRrezQH0qIdt23rivvf2R7CCOWSmgzowrswmtHdgeEVbodUIBPTNp7qzlUk9gDp6vW0XrOC4qEFI+VaY5PsEOXrrxZmI3gGGJgsbfzRvzvvupQcLNERniJ67r/uumbForpL0x1c65scKuMWwcn1wqt2OLbDoIIuM31Ph2HX/09TTqECU7CTvqLT5MnbZHXGjY9c3ch+sY3tSfaEX6aazl/Dqx28c7boCEw=
file:
- ${TRAVIS_TAG}-bundle.txt
- ${TRAVIS_TAG}-bundle.tar.gz
diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml
index b39d0e5e23..29b1d106cd 100644
--- a/erts/doc/src/erlang.xml
+++ b/erts/doc/src/erlang.xml
@@ -6170,7 +6170,7 @@ true</pre>
<p>Monitors the new process (like
<seealso marker="#monitor/2"><c>monitor/2</c></seealso> does).</p>
</item>
- <tag><c>{priority, <anno>Level</anno></c></tag>
+ <tag><c>{priority, <anno>Level</anno>}</c></tag>
<item>
<p>Sets the priority of the new process. Equivalent to
executing <seealso marker="#process_flag_priority">
@@ -7581,7 +7581,7 @@ ok
</func>
<func>
- <name name="system_info" arity="1" clause_i="75"/>
+ <name name="system_info" arity="1" clause_i="76"/>
<fsummary>System info overview.</fsummary>
<desc>
<p>Returns information about the current system.
@@ -7629,6 +7629,7 @@ ok
<p>
<seealso marker="#system_info_atom_count"><c>atom_count</c></seealso>,
<seealso marker="#system_info_atom_limit"><c>atom_limit</c></seealso>,
+ <seealso marker="#system_info_ets_count"><c>ets_count</c></seealso>,
<seealso marker="#system_info_ets_limit"><c>ets_limit</c></seealso>,
<seealso marker="#system_info_port_count"><c>port_count</c></seealso>,
<seealso marker="#system_info_port_limit"><c>port_limit</c></seealso>,
@@ -7872,8 +7873,8 @@ ok
<name name="system_info" arity="1" clause_i="12"
anchor="system_info_cpu_topology"/> <!-- cpu_topology -->
<name name="system_info" arity="1" clause_i="13"/> <!-- {cpu_topology, _} -->
- <name name="system_info" arity="1" clause_i="37"/> <!-- logical_processors -->
- <name name="system_info" arity="1" clause_i="72"/> <!-- update_cpu_info -->
+ <name name="system_info" arity="1" clause_i="38"/> <!-- logical_processors -->
+ <name name="system_info" arity="1" clause_i="73"/> <!-- update_cpu_info -->
<fsummary>Information about the CPU topology of the system.</fsummary>
<type name="cpu_topology"/>
<type name="level_entry"/>
@@ -8024,16 +8025,16 @@ ok
</func>
<func>
- <name name="system_info" arity="1" clause_i="30"
+ <name name="system_info" arity="1" clause_i="31"
anchor="system_info_process"/> <!-- fullsweep_after -->
- <name name="system_info" arity="1" clause_i="31"/> <!-- garbage_collection -->
- <name name="system_info" arity="1" clause_i="32"/> <!-- heap_sizes -->
- <name name="system_info" arity="1" clause_i="33"/> <!-- heap_type -->
- <name name="system_info" arity="1" clause_i="39"/> <!-- max_heap_size -->
- <name name="system_info" arity="1" clause_i="40"/> <!-- message_queue_data -->
- <name name="system_info" arity="1" clause_i="41"/> <!-- min_heap_size -->
- <name name="system_info" arity="1" clause_i="42"/> <!-- min_bin_vheap_size -->
- <name name="system_info" arity="1" clause_i="56"/> <!-- procs -->
+ <name name="system_info" arity="1" clause_i="32"/> <!-- garbage_collection -->
+ <name name="system_info" arity="1" clause_i="33"/> <!-- heap_sizes -->
+ <name name="system_info" arity="1" clause_i="34"/> <!-- heap_type -->
+ <name name="system_info" arity="1" clause_i="40"/> <!-- max_heap_size -->
+ <name name="system_info" arity="1" clause_i="41"/> <!-- message_queue_data -->
+ <name name="system_info" arity="1" clause_i="42"/> <!-- min_heap_size -->
+ <name name="system_info" arity="1" clause_i="43"/> <!-- min_bin_vheap_size -->
+ <name name="system_info" arity="1" clause_i="57"/> <!-- procs -->
<fsummary>Information about the default process heap settings.</fsummary>
<type name="message_queue_data"/>
<type name="max_heap_size"/>
@@ -8143,14 +8144,14 @@ ok
</func>
<func>
- <name name="system_info" arity="1" clause_i="6"
- anchor="system_info_limits"/> <!-- atom_count -->
+ <name name="system_info" arity="1" clause_i="6" anchor="system_info_limits"/> <!-- atom_count -->
<name name="system_info" arity="1" clause_i="7"/> <!-- atom_limit -->
- <name name="system_info" arity="1" clause_i="29"/> <!-- ets_limit -->
- <name name="system_info" arity="1" clause_i="52"/> <!-- port_count -->
- <name name="system_info" arity="1" clause_i="53"/> <!-- port_limit -->
- <name name="system_info" arity="1" clause_i="54"/> <!-- process_count -->
- <name name="system_info" arity="1" clause_i="55"/> <!-- process_limit -->
+ <name name="system_info" arity="1" clause_i="29"/> <!-- ets_count -->
+ <name name="system_info" arity="1" clause_i="30"/> <!-- ets_limit -->
+ <name name="system_info" arity="1" clause_i="53"/> <!-- port_count -->
+ <name name="system_info" arity="1" clause_i="54"/> <!-- port_limit -->
+ <name name="system_info" arity="1" clause_i="55"/> <!-- process_count -->
+ <name name="system_info" arity="1" clause_i="56"/> <!-- process_limit -->
<fsummary>Information about various system limits.</fsummary>
<desc>
<marker id="system_info_limits"/>
@@ -8173,7 +8174,7 @@ ok
<c>erl(1)</c>.
</p>
</item>
- <tag><marker id="system_info_ets_count"/>
+ <tag><marker id="system_info_ets_count"/>
<c>ets_count</c></tag>
<item>
<p>Returns the number of ETS tables currently existing at the
@@ -8225,13 +8226,13 @@ ok
<func>
<name name="system_info" arity="1" clause_i="26"
anchor="system_info_time"/> <!-- end_time -->
- <name name="system_info" arity="1" clause_i="49"/> <!-- os_monotonic_time_source -->
- <name name="system_info" arity="1" clause_i="50"/> <!-- os_system_time_source -->
- <name name="system_info" arity="1" clause_i="62"/> <!-- start_time -->
- <name name="system_info" arity="1" clause_i="67"/> <!-- time_correction -->
- <name name="system_info" arity="1" clause_i="68"/> <!-- time_offset -->
- <name name="system_info" arity="1" clause_i="69"/> <!-- time_warp_mode -->
- <name name="system_info" arity="1" clause_i="70"/> <!-- tolerant_timeofday -->
+ <name name="system_info" arity="1" clause_i="50"/> <!-- os_monotonic_time_source -->
+ <name name="system_info" arity="1" clause_i="51"/> <!-- os_system_time_source -->
+ <name name="system_info" arity="1" clause_i="63"/> <!-- start_time -->
+ <name name="system_info" arity="1" clause_i="68"/> <!-- time_correction -->
+ <name name="system_info" arity="1" clause_i="69"/> <!-- time_offset -->
+ <name name="system_info" arity="1" clause_i="70"/> <!-- time_warp_mode -->
+ <name name="system_info" arity="1" clause_i="71"/> <!-- tolerant_timeofday -->
<fsummary>Information about system time.</fsummary>
<desc>
<marker id="system_info_time_tags"/>
@@ -8455,16 +8456,16 @@ ok
anchor="system_info_scheduler"/> <!-- dirty_cpu_schedulers -->
<name name="system_info" arity="1" clause_i="18"/> <!-- dirty_cpu_schedulers_online -->
<name name="system_info" arity="1" clause_i="19"/> <!-- dirty_io_schedulers -->
- <name name="system_info" arity="1" clause_i="44"/> <!-- multi_scheduling -->
- <name name="system_info" arity="1" clause_i="45"/> <!-- multi_scheduling_blockers -->
- <name name="system_info" arity="1" clause_i="47"/> <!-- normal_multi_scheduling_blockers -->
- <name name="system_info" arity="1" clause_i="57"/> <!-- scheduler_bind_type -->
- <name name="system_info" arity="1" clause_i="58"/> <!-- scheduler_bindings -->
- <name name="system_info" arity="1" clause_i="59"/> <!-- scheduler_id -->
- <name name="system_info" arity="1" clause_i="60"/> <!-- schedulers -->
- <name name="system_info" arity="1" clause_i="61"/> <!-- smp_support -->
- <name name="system_info" arity="1" clause_i="65"/> <!-- threads -->
- <name name="system_info" arity="1" clause_i="66"/> <!-- thread_pool_size -->
+ <name name="system_info" arity="1" clause_i="45"/> <!-- multi_scheduling -->
+ <name name="system_info" arity="1" clause_i="46"/> <!-- multi_scheduling_blockers -->
+ <name name="system_info" arity="1" clause_i="49"/> <!-- normal_multi_scheduling_blockers -->
+ <name name="system_info" arity="1" clause_i="58"/> <!-- scheduler_bind_type -->
+ <name name="system_info" arity="1" clause_i="59"/> <!-- scheduler_bindings -->
+ <name name="system_info" arity="1" clause_i="60"/> <!-- scheduler_id -->
+ <name name="system_info" arity="1" clause_i="61"/> <!-- schedulers -->
+ <name name="system_info" arity="1" clause_i="62"/> <!-- smp_support -->
+ <name name="system_info" arity="1" clause_i="66"/> <!-- threads -->
+ <name name="system_info" arity="1" clause_i="67"/> <!-- thread_pool_size -->
<fsummary>Information about system schedulers.</fsummary>
<desc>
<marker id="system_info_scheduler_tags"/>
@@ -8851,53 +8852,54 @@ ok
<!-- <name name="system_info" arity="1" clause_i="26"/> end_time -->
<!-- <name name="system_info" arity="1" clause_i="27"/> elib_malloc -->
<!-- <name name="system_info" arity="1" clause_i="28"/> eager_check_io, removed -->
- <!-- <name name="system_info" arity="1" clause_i="29"/> ets_limit -->
- <!-- <name name="system_info" arity="1" clause_i="30"/> fullsweep_after -->
- <!-- <name name="system_info" arity="1" clause_i="31"/> garbage_collection -->
- <!-- <name name="system_info" arity="1" clause_i="32"/> heap_sizes -->
- <!-- <name name="system_info" arity="1" clause_i="33"/> heap_type -->
- <name name="system_info" arity="1" clause_i="34"/> <!-- info -->
- <name name="system_info" arity="1" clause_i="35"/> <!-- kernel_poll -->
- <name name="system_info" arity="1" clause_i="36"/> <!-- loaded -->
- <!-- <name name="system_info" arity="1" clause_i="37"/> logical_processors -->
- <name name="system_info" arity="1" clause_i="38"/> <!-- machine -->
- <!-- <name name="system_info" arity="1" clause_i="39"/> max_heap_size -->
- <!-- <name name="system_info" arity="1" clause_i="40"/> message_queue_data -->
- <!-- <name name="system_info" arity="1" clause_i="41"/> min_heap_size -->
- <!-- <name name="system_info" arity="1" clause_i="42"/> min_bin_vheap_size -->
- <name name="system_info" arity="1" clause_i="43"/> <!-- modified_timing_level -->
- <!-- <name name="system_info" arity="1" clause_i="44"/> multi_scheduling -->
- <!-- <name name="system_info" arity="1" clause_i="45"/> multi_scheduling_blockers -->
- <name name="system_info" arity="1" clause_i="46"/> <!-- nif_version -->
- <!-- n<name name="system_info" arity="1" clause_i="47"/> ormal_multi_scheduling_blockers -->
- <name name="system_info" arity="1" clause_i="48"/> <!-- otp_release -->
- <!-- <name name="system_info" arity="1" clause_i="49"/> os_monotonic_time_source -->
- <!-- <name name="system_info" arity="1" clause_i="50"/> os_system_time_source -->
- <name name="system_info" arity="1" clause_i="51"/> <!-- port_parallelism -->
- <!-- <name name="system_info" arity="1" clause_i="52"/> port_count -->
- <!-- <name name="system_info" arity="1" clause_i="53"/> port_limit -->
- <!-- <name name="system_info" arity="1" clause_i="54"/> process_count -->
- <!-- <name name="system_info" arity="1" clause_i="55"/> process_limit -->
- <!-- <name name="system_info" arity="1" clause_i="56"/> procs -->
- <!-- <name name="system_info" arity="1" clause_i="57"/> scheduler_bind_type -->
- <!-- <name name="system_info" arity="1" clause_i="58"/> scheduler_bindings -->
- <!-- <name name="system_info" arity="1" clause_i="59"/> scheduler_id -->
- <!-- <name name="system_info" arity="1" clause_i="60"/> schedulers -->
- <!-- <name name="system_info" arity="1" clause_i="61"/> smp_support -->
- <!-- <name name="system_info" arity="1" clause_i="62"/> start_time -->
- <name name="system_info" arity="1" clause_i="63"/> <!-- system_version -->
- <name name="system_info" arity="1" clause_i="64"/> <!-- system_architecture -->
- <!-- <name name="system_info" arity="1" clause_i="65"/> threads -->
- <!-- <name name="system_info" arity="1" clause_i="66"/> thread_pool_size -->
- <!-- <name name="system_info" arity="1" clause_i="67"/> time_correction -->
- <!-- <name name="system_info" arity="1" clause_i="68"/> time_offset -->
- <!-- <name name="system_info" arity="1" clause_i="69"/> time_warp_mode -->
- <!-- <name name="system_info" arity="1" clause_i="70"/> tolerant_timeofday -->
- <name name="system_info" arity="1" clause_i="71"/> <!-- trace_control_word -->
- <!-- <name name="system_info" arity="1" clause_i="72"/> update_cpu_info -->
- <name name="system_info" arity="1" clause_i="73"/> <!-- version -->
- <name name="system_info" arity="1" clause_i="74"/> <!-- wordsize -->
- <!-- <name name="system_info" arity="1" clause_i="75"/> overview -->
+ <!-- <name name="system_info" arity="1" clause_i="29"/> ets_count -->
+ <!-- <name name="system_info" arity="1" clause_i="30"/> ets_limit -->
+ <!-- <name name="system_info" arity="1" clause_i="31"/> fullsweep_after -->
+ <!-- <name name="system_info" arity="1" clause_i="32"/> garbage_collection -->
+ <!-- <name name="system_info" arity="1" clause_i="33"/> heap_sizes -->
+ <!-- <name name="system_info" arity="1" clause_i="34"/> heap_type -->
+ <name name="system_info" arity="1" clause_i="35"/> <!-- info -->
+ <name name="system_info" arity="1" clause_i="36"/> <!-- kernel_poll -->
+ <name name="system_info" arity="1" clause_i="37"/> <!-- loaded -->
+ <!-- <name name="system_info" arity="1" clause_i="38"/> logical_processors -->
+ <name name="system_info" arity="1" clause_i="39"/> <!-- machine -->
+ <!-- <name name="system_info" arity="1" clause_i="40"/> max_heap_size -->
+ <!-- <name name="system_info" arity="1" clause_i="41"/> message_queue_data -->
+ <!-- <name name="system_info" arity="1" clause_i="42"/> min_heap_size -->
+ <!-- <name name="system_info" arity="1" clause_i="43"/> min_bin_vheap_size -->
+ <name name="system_info" arity="1" clause_i="44"/> <!-- modified_timing_level -->
+ <!-- <name name="system_info" arity="1" clause_i="45"/> multi_scheduling -->
+ <!-- <name name="system_info" arity="1" clause_i="46"/> multi_scheduling_blockers -->
+ <name name="system_info" arity="1" clause_i="47"/> <!-- nif_version -->
+ <!-- n<name name="system_info" arity="1" clause_i="48"/> ormal_multi_scheduling_blockers -->
+ <name name="system_info" arity="1" clause_i="49"/> <!-- otp_release -->
+ <!-- <name name="system_info" arity="1" clause_i="50"/> os_monotonic_time_source -->
+ <!-- <name name="system_info" arity="1" clause_i="51"/> os_system_time_source -->
+ <name name="system_info" arity="1" clause_i="52"/> <!-- port_parallelism -->
+ <!-- <name name="system_info" arity="1" clause_i="53"/> port_count -->
+ <!-- <name name="system_info" arity="1" clause_i="54"/> port_limit -->
+ <!-- <name name="system_info" arity="1" clause_i="55"/> process_count -->
+ <!-- <name name="system_info" arity="1" clause_i="56"/> process_limit -->
+ <!-- <name name="system_info" arity="1" clause_i="57"/> procs -->
+ <!-- <name name="system_info" arity="1" clause_i="58"/> scheduler_bind_type -->
+ <!-- <name name="system_info" arity="1" clause_i="59"/> scheduler_bindings -->
+ <!-- <name name="system_info" arity="1" clause_i="60"/> scheduler_id -->
+ <!-- <name name="system_info" arity="1" clause_i="61"/> schedulers -->
+ <!-- <name name="system_info" arity="1" clause_i="62"/> smp_support -->
+ <!-- <name name="system_info" arity="1" clause_i="63"/> start_time -->
+ <name name="system_info" arity="1" clause_i="64"/> <!-- system_version -->
+ <name name="system_info" arity="1" clause_i="65"/> <!-- system_architecture -->
+ <!-- <name name="system_info" arity="1" clause_i="66"/> threads -->
+ <!-- <name name="system_info" arity="1" clause_i="67"/> thread_pool_size -->
+ <!-- <name name="system_info" arity="1" clause_i="68"/> time_correction -->
+ <!-- <name name="system_info" arity="1" clause_i="69"/> time_offset -->
+ <!-- <name name="system_info" arity="1" clause_i="70"/> time_warp_mode -->
+ <!-- <name name="system_info" arity="1" clause_i="71"/> tolerant_timeofday -->
+ <name name="system_info" arity="1" clause_i="72"/> <!-- trace_control_word -->
+ <!-- <name name="system_info" arity="1" clause_i="73"/> update_cpu_info -->
+ <name name="system_info" arity="1" clause_i="74"/> <!-- version -->
+ <name name="system_info" arity="1" clause_i="75"/> <!-- wordsize -->
+ <!-- <name name="system_info" arity="1" clause_i="76"/> overview -->
<fsummary>Information about the system.</fsummary>
<desc>
<marker id="system_info_misc_tags"/>
diff --git a/erts/doc/src/notes.xml b/erts/doc/src/notes.xml
index 856020dfc9..1531935f36 100644
--- a/erts/doc/src/notes.xml
+++ b/erts/doc/src/notes.xml
@@ -1010,6 +1010,21 @@
</section>
+<section><title>Erts 9.3.3.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>Fixed a rare bug that could cause processes to be
+ scheduled after they had been freed.</p>
+ <p>
+ Own Id: OTP-15067 Aux Id: ERL-573 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Erts 9.3.3</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/erts/emulator/beam/erl_process.h b/erts/emulator/beam/erl_process.h
index a60e117bab..8d20ccdf90 100644
--- a/erts/emulator/beam/erl_process.h
+++ b/erts/emulator/beam/erl_process.h
@@ -293,7 +293,7 @@ typedef enum {
* highest index...
*
* Remember to update description in erts_pre_init_process()
- * when adding new flags...
+ * and etp-commands when adding new flags...
*/
typedef enum {
diff --git a/erts/etc/unix/cerl.src b/erts/etc/unix/cerl.src
index 3572fdd954..896e4c8e45 100644
--- a/erts/etc/unix/cerl.src
+++ b/erts/etc/unix/cerl.src
@@ -69,15 +69,6 @@ cxargs_add() {
done
}
-eeargs=
-eeargs_add() {
- while [ $# -gt 0 ]; do
- cargs="$cargs $1"
- eeargs="$eeargs $1"
- shift
- done
-}
-
core=
GDB=
@@ -97,8 +88,6 @@ TARGET=%TARGET%
PROGNAME=$ROOTDIR/bin/cerl
EMU=beam
-PRELOADED=$ROOTDIR/erts/preloaded/ebin
-
while [ $# -gt 0 ]; do
case "$1" in
@@ -255,7 +244,7 @@ EXEC=$BINDIR/erlexec
PROGNAME="$PROGNAME$cargs"
EMU="$EMU$TYPE"
-EMU_NAME=`$EXEC -emu_name_exit $eeargs`
+EMU_NAME=`$EXEC -emu_name_exit`
if [ $skip_erlexec = yes ]; then
emu_xargs=`echo $xargs | sed "s|+|-|g"`
@@ -269,8 +258,6 @@ if [ $skip_erlexec = yes ]; then
'
set -- $beam_args
IFS="$SAVE_IFS"
-else
- xargs="$xargs -pz $PRELOADED --"
fi
if [ "x$GDB" = "x" ]; then
if [ $run_valgrind = yes ]; then
@@ -316,12 +303,12 @@ if [ "x$GDB" = "x" ]; then
sched_arg=
fi
- exec $taskset1 valgrind $valgrind_xml $valgrind_log $valgrind_misc_flags $BINDIR/$EMU_NAME $sched_arg $emu_xargs "$@" -pz $PRELOADED
+ exec $taskset1 valgrind $valgrind_xml $valgrind_log $valgrind_misc_flags $BINDIR/$EMU_NAME $sched_arg $emu_xargs "$@"
elif [ $run_rr = yes ]; then
- exec rr record --ignore-nested $BINDIR/$EMU_NAME $emu_xargs "$@" -pz $PRELOADED
+ exec rr record --ignore-nested $BINDIR/$EMU_NAME $emu_xargs "$@"
else
- exec $EXEC $eeargs $xargs ${1+"$@"}
+ exec $EXEC $xargs ${1+"$@"}
fi
elif [ "x$GDB" = "xgdb" ]; then
case "x$core" in
diff --git a/erts/etc/unix/etp-commands.in b/erts/etc/unix/etp-commands.in
index 5b89621733..b12a205ba7 100644
--- a/erts/etc/unix/etp-commands.in
+++ b/erts/etc/unix/etp-commands.in
@@ -2734,25 +2734,37 @@ define etp-aux-work-flags
printf " fix-alloc-lower-lim"
end
if ($arg0 & 0x10)
- printf " async-ready"
+ printf " later-op"
end
if ($arg0 & 0x20)
- printf " async-ready-clean"
+ printf " canceled-timers"
end
if ($arg0 & 0x40)
- printf " misc-work-thr-prgr"
+ printf " canceled-timers-thr-prgr"
end
if ($arg0 & 0x80)
- printf " misc-work"
+ printf " async-ready"
end
if ($arg0 & 0x100)
- printf " check-children"
+ printf " async-ready-clean"
end
if ($arg0 & 0x200)
- printf " set-tmo"
+ printf " misc-thr-prgr"
end
if ($arg0 & 0x400)
- printf " mseg-cached-check"
+ printf " misc"
+ end
+ if ($arg0 & 0x800)
+ printf " set-tmo"
+ end
+ if ($arg0 & 0x1000)
+ printf " mseg-cache-check"
+ end
+ if ($arg0 & 0x2000)
+ printf " yield"
+ end
+ if ($arg0 & 0x1000)
+ printf " reap-ports"
end
if ($arg0 & ~0x7ff)
printf " GARBAGE"
diff --git a/erts/preloaded/src/erlang.erl b/erts/preloaded/src/erlang.erl
index f4f31b1e4b..75f6901258 100644
--- a/erts/preloaded/src/erlang.erl
+++ b/erts/preloaded/src/erlang.erl
@@ -2681,11 +2681,12 @@ tuple_to_list(_Tuple) ->
(dist_ctrl) -> {Node :: node(),
ControllingEntity :: port() | pid()};
(driver_version) -> string();
- (dynamic_trace) -> none | dtrace | systemtap;
+ (dynamic_trace) -> none | dtrace | systemtap;
(dynamic_trace_probes) -> boolean();
(end_time) -> non_neg_integer();
(elib_malloc) -> false;
(eager_check_io) -> boolean();
+ (ets_count) -> pos_integer();
(ets_limit) -> pos_integer();
(fullsweep_after) -> {fullsweep_after, non_neg_integer()};
(garbage_collection) -> [{atom(), integer()}];
diff --git a/lib/erl_interface/doc/src/notes.xml b/lib/erl_interface/doc/src/notes.xml
index 5b81f795b2..1438317d8d 100644
--- a/lib/erl_interface/doc/src/notes.xml
+++ b/lib/erl_interface/doc/src/notes.xml
@@ -69,6 +69,24 @@
</section>
+<section><title>Erl_Interface 3.10.2.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Make <c>ei_connect</c> and friends also accept state
+ <c>ok_simultaneous</c> during handshake, which means the
+ other node has initiated a connection setup that will be
+ cancelled in favor of this connection.</p>
+ <p>
+ Own Id: OTP-15161 Aux Id: ERIERL-191 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Erl_Interface 3.10.2</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/erl_interface/src/connect/ei_connect.c b/lib/erl_interface/src/connect/ei_connect.c
index f5034ca3e8..34f4620866 100644
--- a/lib/erl_interface/src/connect/ei_connect.c
+++ b/lib/erl_interface/src/connect/ei_connect.c
@@ -1357,11 +1357,14 @@ static int recv_status(int fd, unsigned ms)
"<- RECV_STATUS socket read failed (%d)", rlen);
goto error;
}
- if (rlen == 3 && buf[0] == 's' && buf[1] == 'o' &&
- buf[2] == 'k') {
+
+ EI_TRACE_CONN2("recv_status",
+ "<- RECV_STATUS (%.*s)", (rlen>20 ? 20 : rlen), buf);
+
+ if (rlen >= 3 && buf[0] == 's' && buf[1] == 'o' && buf[2] == 'k') {
+ /* Expecting "sok" or "sok_simultaneous" */
if (!is_static)
free(buf);
- EI_TRACE_CONN0("recv_status","<- RECV_STATUS (ok)");
return 0;
}
error:
diff --git a/lib/ftp/doc/src/ftp.xml b/lib/ftp/doc/src/ftp.xml
index 3dbd3ed403..23a9e3fec7 100644
--- a/lib/ftp/doc/src/ftp.xml
+++ b/lib/ftp/doc/src/ftp.xml
@@ -546,11 +546,12 @@
<v>start_option() = {verbose, verbose()} | {debug, debug()}</v>
<v>verbose() = boolean() (default is false)</v>
<v>debug() = disable | debug | trace (default is disable)</v>
- <v>open_option() = {ipfamily, ipfamily()} | {port, port()} | {mode, mode()} | {tls, tls_options()} | {timeout, timeout()} | {dtimeout, dtimeout()} | {progress, progress()}</v>
+ <v>open_option() = {ipfamily, ipfamily()} | {port, port()} | {mode, mode()} | {tls, tls_options()} | {timeout, timeout()} | {dtimeout, dtimeout()} | {progress, progress() | {sock_ctrl, sock_opts()} | {sock_data_act, sock_opts()} | {sock_data_pass, sock_opts()} }</v>
<v>ipfamily() = inet | inet6 | inet6fb4 (default is inet)</v>
<v>port() = integer() > 0 (default is 21)</v>
<v>mode() = active | passive (default is passive)</v>
<v>tls_options() = [<seealso marker="ssl:ssl#type-ssloption">ssl:ssloption()</seealso>]</v>
+ <v>sock_opts() = [<seealso marker="kernel:gen_tcp#type-option">gen_tcp:option()</seealso> except for ipv6_v6only, active, packet, mode, packet_size and header</v>
<v>timeout() = integer() > 0 (default is 60000 milliseconds)</v>
<v>dtimeout() = integer() > 0 | infinity (default is infinity)</v>
<v>pogress() = ignore | {module(), function(), initial_data()} (default is ignore)</v>
@@ -573,6 +574,11 @@
is used for securing both the control connection and the data sessions.
</p>
+ <p>The options <c>sock_ctrl</c>, <c>sock_data_act</c> and <c>sock_data_pass</c> passes options down to
+ the underlying transport layer (tcp). The default value for <c>sock_ctrl</c> is <c>[]</c>. Both
+ <c>sock_data_act</c> and <c>sock_data_pass</c> uses the value of <c>sock_ctrl</c> as default value.
+ </p>
+
<p>A session opened in this way is closed using function
<seealso marker="#close">close</seealso>.</p>
diff --git a/lib/ftp/src/ftp.erl b/lib/ftp/src/ftp.erl
index 8790bfec13..40f6b53fa3 100644
--- a/lib/ftp/src/ftp.erl
+++ b/lib/ftp/src/ftp.erl
@@ -101,6 +101,9 @@
%% data needed further on.
caller = undefined, % term()
ipfamily, % inet | inet6 | inet6fb4
+ sockopts_ctrl = [],
+ sockopts_data_passive = [],
+ sockopts_data_active = [],
progress = ignore, % ignore | pid()
dtimeout = ?DATA_ACCEPT_TIMEOUT, % non_neg_integer() | infinity
tls_upgrading_data_connection = false,
@@ -135,9 +138,10 @@ start_standalone(Options) ->
try
{ok, StartOptions} = start_options(Options),
{ok, OpenOptions} = open_options(Options),
+ {ok, SocketOptions} = socket_options(Options),
case start_link(StartOptions, []) of
{ok, Pid} ->
- call(Pid, {open, ip_comm, OpenOptions}, plain);
+ call(Pid, {open, ip_comm, OpenOptions, SocketOptions}, plain);
Error1 ->
Error1
end
@@ -149,10 +153,11 @@ start_standalone(Options) ->
start_service(Options) ->
try
{ok, StartOptions} = start_options(Options),
- {ok, OpenOptions} = open_options(Options),
+ {ok, OpenOptions} = open_options(Options),
+ {ok, SocketOptions} = socket_options(Options),
case ftp_sup:start_child([[[{client, self()} | StartOptions], []]]) of
{ok, Pid} ->
- call(Pid, {open, ip_comm, OpenOptions}, plain);
+ call(Pid, {open, ip_comm, OpenOptions, SocketOptions}, plain);
Error1 ->
Error1
end
@@ -200,9 +205,10 @@ open({option_list, Options}) when is_list(Options) ->
try
{ok, StartOptions} = start_options(Options),
{ok, OpenOptions} = open_options(Options),
+ {ok, SockOpts} = socket_options(Options),
case ftp_sup:start_child([[[{client, self()} | StartOptions], []]]) of
{ok, Pid} ->
- call(Pid, {open, ip_comm, OpenOptions}, plain);
+ call(Pid, {open, ip_comm, OpenOptions, SockOpts}, plain);
Error1 ->
Error1
end
@@ -227,9 +233,10 @@ open(Host, Opts) when is_list(Opts) ->
try
{ok, StartOptions} = start_options(Opts),
{ok, OpenOptions} = open_options([{host, Host}|Opts]),
+ {ok, SocketOptions} = socket_options(Opts),
case start_link(StartOptions, []) of
{ok, Pid} ->
- do_open(Pid, OpenOptions, tls_options(Opts));
+ do_open(Pid, OpenOptions, SocketOptions, tls_options(Opts));
Error1 ->
Error1
end
@@ -238,8 +245,8 @@ open(Host, Opts) when is_list(Opts) ->
Error2
end.
-do_open(Pid, OpenOptions, TLSOpts) ->
- case call(Pid, {open, ip_comm, OpenOptions}, plain) of
+do_open(Pid, OpenOptions, SocketOptions, TLSOpts) ->
+ case call(Pid, {open, ip_comm, OpenOptions, SocketOptions}, plain) of
{ok, Pid} ->
maybe_tls_upgrade(Pid, TLSOpts);
Error ->
@@ -1026,7 +1033,7 @@ handle_call({_,latest_ctrl_response}, _, #state{latest_ctrl_response=Resp} = Sta
handle_call({Pid, _}, _, #state{owner = Owner} = State) when Owner =/= Pid ->
{reply, {error, not_connection_owner}, State};
-handle_call({_, {open, ip_comm, Opts}}, From, State) ->
+handle_call({_, {open, ip_comm, Opts, {CtrlOpts, DataPassOpts, DataActOpts}}}, From, State) ->
case key_search(host, Opts, undefined) of
undefined ->
{stop, normal, {error, ehost}, State};
@@ -1043,6 +1050,9 @@ handle_call({_, {open, ip_comm, Opts}}, From, State) ->
mode = Mode,
progress = progress(Progress),
ipfamily = IpFamily,
+ sockopts_ctrl = CtrlOpts,
+ sockopts_data_passive = DataPassOpts,
+ sockopts_data_active = DataActOpts,
dtimeout = DTimeout,
ftp_extension = FtpExt},
@@ -1055,28 +1065,6 @@ handle_call({_, {open, ip_comm, Opts}}, From, State) ->
end
end;
-handle_call({_, {open, ip_comm, Host, Opts}}, From, State) ->
- Mode = key_search(mode, Opts, ?DEFAULT_MODE),
- Port = key_search(port, Opts, ?FTP_PORT),
- Timeout = key_search(timeout, Opts, ?CONNECTION_TIMEOUT),
- DTimeout = key_search(dtimeout, Opts, ?DATA_ACCEPT_TIMEOUT),
- Progress = key_search(progress, Opts, ignore),
- FtpExt = key_search(ftp_extension, Opts, ?FTP_EXT_DEFAULT),
-
- State2 = State#state{client = From,
- mode = Mode,
- progress = progress(Progress),
- dtimeout = DTimeout,
- ftp_extension = FtpExt},
-
- case setup_ctrl_connection(Host, Port, Timeout, State2) of
- {ok, State3, WaitTimeout} ->
- {noreply, State3, WaitTimeout};
- {error, _Reason} ->
- gen_server:reply(From, {error, ehost}),
- {stop, normal, State2#state{client = undefined}}
- end;
-
handle_call({_, {open, tls_upgrade, TLSOptions}}, From, State) ->
_ = send_ctrl_message(State, mk_cmd("AUTH TLS", [])),
activate_ctrl_connection(State),
@@ -1659,11 +1647,12 @@ handle_ctrl_result({pos_compl, Lines},
client = From,
caller = {setup_data_connection, Caller},
csock = CSock,
+ sockopts_data_passive = SockOpts,
timeout = Timeout}
= State) ->
[_, PortStr | _] = lists:reverse(string:tokens(Lines, "|")),
{ok, {IP, _}} = peername(CSock),
- case connect(IP, list_to_integer(PortStr), Timeout, State) of
+ case connect(IP, list_to_integer(PortStr), SockOpts, Timeout, State) of
{ok, _, Socket} ->
handle_caller(State#state{caller = Caller, dsock = {tcp, Socket}});
{error, _Reason} = Error ->
@@ -1676,7 +1665,8 @@ handle_ctrl_result({pos_compl, Lines},
ipfamily = inet,
client = From,
caller = {setup_data_connection, Caller},
- timeout = Timeout,
+ timeout = Timeout,
+ sockopts_data_passive = SockOpts,
ftp_extension = false} = State) ->
{_, [?LEFT_PAREN | Rest]} =
@@ -1690,7 +1680,7 @@ handle_ctrl_result({pos_compl, Lines},
Port = (P1 * 256) + P2,
?DBG('<--data tcp connect to ~p:~p, Caller=~p~n',[IP,Port,Caller]),
- case connect(IP, Port, Timeout, State) of
+ case connect(IP, Port, SockOpts, Timeout, State) of
{ok, _, Socket} ->
handle_caller(State#state{caller = Caller, dsock = {tcp,Socket}});
{error, _Reason} = Error ->
@@ -1705,13 +1695,14 @@ handle_ctrl_result({pos_compl, Lines},
caller = {setup_data_connection, Caller},
csock = CSock,
timeout = Timeout,
+ sockopts_data_passive = SockOpts,
ftp_extension = true} = State) ->
[_, PortStr | _] = lists:reverse(string:tokens(Lines, "|")),
{ok, {IP, _}} = peername(CSock),
?DBG('<--data tcp connect to ~p:~p, Caller=~p~n',[IP,PortStr,Caller]),
- case connect(IP, list_to_integer(PortStr), Timeout, State) of
+ case connect(IP, list_to_integer(PortStr), SockOpts, Timeout, State) of
{ok, _, Socket} ->
handle_caller(State#state{caller = Caller, dsock = {tcp, Socket}});
{error, _Reason} = Error ->
@@ -2075,9 +2066,9 @@ handle_caller(#state{caller = {transfer_data, {Cmd, Bin, RemoteFile}}} =
%% Connect to FTP server at Host (default is TCP port 21)
%% in order to establish a control connection.
-setup_ctrl_connection(Host, Port, Timeout, State) ->
+setup_ctrl_connection(Host, Port, Timeout, #state{sockopts_ctrl = SockOpts} = State) ->
MsTime = erlang:monotonic_time(),
- case connect(Host, Port, Timeout, State) of
+ case connect(Host, Port, SockOpts, Timeout, State) of
{ok, IpFam, CSock} ->
NewState = State#state{csock = {tcp, CSock}, ipfamily = IpFam},
activate_ctrl_connection(NewState),
@@ -2095,12 +2086,15 @@ setup_ctrl_connection(Host, Port, Timeout, State) ->
setup_data_connection(#state{mode = active,
caller = Caller,
csock = CSock,
+ sockopts_data_active = SockOpts,
ftp_extension = FtpExt} = State) ->
case (catch sockname(CSock)) of
- {ok, {{_, _, _, _, _, _, _, _} = IP, _}} ->
+ {ok, {{_, _, _, _, _, _, _, _} = IP0, _}} ->
+ IP = proplists:get_value(ip, SockOpts, IP0),
{ok, LSock} =
gen_tcp:listen(0, [{ip, IP}, {active, false},
- inet6, binary, {packet, 0}]),
+ inet6, binary, {packet, 0} |
+ lists:keydelete(ip,1,SockOpts)]),
{ok, {_, Port}} = sockname({tcp,LSock}),
IpAddress = inet_parse:ntoa(IP),
Cmd = mk_cmd("EPRT |2|~s|~p|", [IpAddress, Port]),
@@ -2108,9 +2102,11 @@ setup_data_connection(#state{mode = active,
activate_ctrl_connection(State),
{noreply, State#state{caller = {setup_data_connection,
{LSock, Caller}}}};
- {ok, {{_,_,_,_} = IP, _}} ->
+ {ok, {{_,_,_,_} = IP0, _}} ->
+ IP = proplists:get_value(ip, SockOpts, IP0),
{ok, LSock} = gen_tcp:listen(0, [{ip, IP}, {active, false},
- binary, {packet, 0}]),
+ binary, {packet, 0} |
+ lists:keydelete(ip,1,SockOpts)]),
{ok, Port} = inet:port(LSock),
_ = case FtpExt of
false ->
@@ -2149,41 +2145,41 @@ setup_data_connection(#state{mode = passive, ipfamily = inet,
activate_ctrl_connection(State),
{noreply, State#state{caller = {setup_data_connection, Caller}}}.
-connect(Host, Port, Timeout, #state{ipfamily = inet = IpFam}) ->
- connect2(Host, Port, IpFam, Timeout);
+connect(Host, Port, SockOpts, Timeout, #state{ipfamily = inet = IpFam}) ->
+ connect2(Host, Port, IpFam, SockOpts, Timeout);
-connect(Host, Port, Timeout, #state{ipfamily = inet6 = IpFam}) ->
- connect2(Host, Port, IpFam, Timeout);
+connect(Host, Port, SockOpts, Timeout, #state{ipfamily = inet6 = IpFam}) ->
+ connect2(Host, Port, IpFam, SockOpts, Timeout);
-connect(Host, Port, Timeout, #state{ipfamily = inet6fb4}) ->
+connect(Host, Port, SockOpts, Timeout, #state{ipfamily = inet6fb4}) ->
case inet:getaddr(Host, inet6) of
{ok, {0, 0, 0, 0, 0, 16#ffff, _, _} = IPv6} ->
case inet:getaddr(Host, inet) of
{ok, IPv4} ->
IpFam = inet,
- connect2(IPv4, Port, IpFam, Timeout);
+ connect2(IPv4, Port, IpFam, SockOpts, Timeout);
_ ->
IpFam = inet6,
- connect2(IPv6, Port, IpFam, Timeout)
+ connect2(IPv6, Port, IpFam, SockOpts, Timeout)
end;
{ok, IPv6} ->
IpFam = inet6,
- connect2(IPv6, Port, IpFam, Timeout);
+ connect2(IPv6, Port, IpFam, SockOpts, Timeout);
_ ->
case inet:getaddr(Host, inet) of
{ok, IPv4} ->
IpFam = inet,
- connect2(IPv4, Port, IpFam, Timeout);
+ connect2(IPv4, Port, IpFam, SockOpts, Timeout);
Error ->
Error
end
end.
-connect2(Host, Port, IpFam, Timeout) ->
- Opts = [IpFam, binary, {packet, 0}, {active, false}],
+connect2(Host, Port, IpFam, SockOpts, Timeout) ->
+ Opts = [IpFam, binary, {packet, 0}, {active, false} | SockOpts],
case gen_tcp:connect(Host, Port, Opts, Timeout) of
{ok, Sock} ->
{ok, IpFam, Sock};
@@ -2553,6 +2549,32 @@ open_options(Options) ->
{ftp_extension, ValidateFtpExtension, false, ?FTP_EXT_DEFAULT}],
validate_options(Options, ValidOptions, []).
+socket_options(Options) ->
+ CtrlOpts = proplists:get_value(sock_ctrl, Options, []),
+ DataActOpts = proplists:get_value(sock_data_act, Options, CtrlOpts),
+ DataPassOpts = proplists:get_value(sock_data_pass, Options, CtrlOpts),
+ case [O || O <- lists:usort(CtrlOpts++DataPassOpts++DataActOpts),
+ not valid_socket_option(O)] of
+ [] ->
+ {ok, {CtrlOpts, DataPassOpts, DataActOpts}};
+ Invalid ->
+ throw({error,{sock_opts,Invalid}})
+ end.
+
+
+valid_socket_option(inet ) -> false;
+valid_socket_option(inet6 ) -> false;
+valid_socket_option({ipv6_v6only, _}) -> false;
+valid_socket_option({active,_} ) -> false;
+valid_socket_option({packet,_} ) -> false;
+valid_socket_option({mode,_} ) -> false;
+valid_socket_option(binary ) -> false;
+valid_socket_option(list ) -> false;
+valid_socket_option({header,_} ) -> false;
+valid_socket_option({packet_size,_} ) -> false;
+valid_socket_option(_) -> true.
+
+
tls_options(Options) ->
%% Options will be validated by ssl application
proplists:get_value(tls, Options, undefined).
diff --git a/lib/inets/doc/src/notes.xml b/lib/inets/doc/src/notes.xml
index f4bf4b1e1f..d967f56576 100644
--- a/lib/inets/doc/src/notes.xml
+++ b/lib/inets/doc/src/notes.xml
@@ -79,7 +79,6 @@
</list>
</section>
-
<section><title>Improvements and New Features</title>
<list>
<item>
@@ -91,7 +90,26 @@
</list>
</section>
-</section>
+ </section>
+
+
+ <section><title>Inets 6.5.2.1</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Options added for setting low-level properties on the
+ underlying TCP connections. The options are:
+ <c>sock_ctrl</c>, <c>sock_data_act</c> and
+ <c>sock_data_pass</c>. See the manual for details.</p>
+ <p>
+ Own Id: OTP-15120 Aux Id: ERIERL-192 </p>
+ </item>
+ </list>
+ </section>
+
+ </section>
<section><title>Inets 6.5.2</title>
diff --git a/lib/kernel/doc/src/notes.xml b/lib/kernel/doc/src/notes.xml
index e1ef8ab387..6e88e98c6d 100644
--- a/lib/kernel/doc/src/notes.xml
+++ b/lib/kernel/doc/src/notes.xml
@@ -314,6 +314,26 @@
</section>
+<section><title>Kernel 5.4.3.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fix some potential buggy behavior in how ticks are sent
+ on inter node distribution connections. Tick is now sent
+ to c-node even if there are unsent buffered data, as
+ c-nodes need ticks in order to send reply ticks. The
+ amount of sent data was calculated wrongly when ticks
+ where suppressed due to unsent buffered data.</p>
+ <p>
+ Own Id: OTP-15162 Aux Id: ERIERL-191 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Kernel 5.4.3</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/runtime_tools/src/observer_backend.erl b/lib/runtime_tools/src/observer_backend.erl
index 063b19e533..3a24986381 100644
--- a/lib/runtime_tools/src/observer_backend.erl
+++ b/lib/runtime_tools/src/observer_backend.erl
@@ -94,7 +94,7 @@ sys_info() ->
{port_limit, erlang:system_info(port_limit)},
{port_count, erlang:system_info(port_count)},
{ets_limit, erlang:system_info(ets_limit)},
- {ets_count, length(ets:all())},
+ {ets_count, erlang:system_info(ets_count)},
{dist_buf_busy_limit, erlang:system_info(dist_buf_busy_limit)}
| MemInfo].
diff --git a/lib/ssh/doc/src/notes.xml b/lib/ssh/doc/src/notes.xml
index c9aa877a7f..2478a8950b 100644
--- a/lib/ssh/doc/src/notes.xml
+++ b/lib/ssh/doc/src/notes.xml
@@ -31,7 +31,6 @@
</header>
<section><title>Ssh 4.7</title>
-
<section><title>Fixed Bugs and Malfunctions</title>
<list>
<item>
@@ -190,6 +189,33 @@
</item>
</list>
</section>
+</section>
+
+<section><title>Ssh 4.6.9.1</title>
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ SFTP clients reported the error reason <c>""</c> if a
+ non-OTP sftp server was killed during a long file
+ transmission.</p>
+ <p>
+ Now the signal name (for example <c>"KILL"</c>) will be
+ the error reason if the server's reason is empty.</p>
+ <p>
+ The documentation also lacked type information about this
+ class of errors.</p>
+ <p>
+ Own Id: OTP-15148 Aux Id: ERIERL-194 </p>
+ </item>
+ <item>
+ <p>
+ Fix ssh_sftp decode error for sftp protocol version 4</p>
+ <p>
+ Own Id: OTP-15149 Aux Id: ERIERL-199 </p>
+ </item>
+ </list>
+ </section>
</section>
diff --git a/lib/ssh/doc/src/ssh_sftp.xml b/lib/ssh/doc/src/ssh_sftp.xml
index 4d2337c30a..ea55126cb3 100644
--- a/lib/ssh/doc/src/ssh_sftp.xml
+++ b/lib/ssh/doc/src/ssh_sftp.xml
@@ -46,9 +46,9 @@
<taglist>
<tag><c>reason()</c></tag>
<item>
- <p>= <c>atom()</c> A description of the reason why an operation failed.</p>
+ <p>= <c>atom() | string() | tuple() </c>A description of the reason why an operation failed.</p>
<p>
- The value is formed from the sftp error codes in the protocol-level responses as defined in
+ The <c>atom()</c> value is formed from the sftp error codes in the protocol-level responses as defined in
<url href="https://tools.ietf.org/id/draft-ietf-secsh-filexfer-13.txt">draft-ietf-secsh-filexfer-13.txt</url>
section 9.1.
</p>
@@ -57,6 +57,10 @@
E.g. the error code <c>SSH_FX_NO_SUCH_FILE</c>
will cause the <c>reason()</c> to be <c>no_such_file</c>.
</p>
+ <p>The <c>string()</c> reason is the error information from the server in case of an exit-signal. If that information is empty, the reason is the exit signal name.
+ </p>
+ <p>The <c>tuple()</c> reason are other errors like the <c>{exit_status,integer()}</c> if the exit status is not 0.
+ </p>
</item>
<tag><c>connection_ref() =</c></tag>
diff --git a/lib/ssh/src/ssh_sftp.erl b/lib/ssh/src/ssh_sftp.erl
index 6e720a47b7..1b2ba5a50b 100644
--- a/lib/ssh/src/ssh_sftp.erl
+++ b/lib/ssh/src/ssh_sftp.erl
@@ -798,13 +798,22 @@ handle_ssh_msg({ssh_cm, _, {signal, _, _}}, State) ->
%% Ignore signals according to RFC 4254 section 6.9.
{ok, State};
-handle_ssh_msg({ssh_cm, _, {exit_signal, ChannelId, _, Error, _}},
+handle_ssh_msg({ssh_cm, _, {exit_signal, ChannelId, Signal, Error0, _}},
State0) ->
+ Error =
+ case Error0 of
+ "" -> Signal;
+ _ -> Error0
+ end,
State = reply_all(State0, {error, Error}),
{stop, ChannelId, State};
handle_ssh_msg({ssh_cm, _, {exit_status, ChannelId, Status}}, State0) ->
- State = reply_all(State0, {error, {exit_status, Status}}),
+ State =
+ case State0 of
+ 0 -> State0;
+ _ -> reply_all(State0, {error, {exit_status, Status}})
+ end,
{stop, ChannelId, State}.
%%--------------------------------------------------------------------
diff --git a/lib/ssh/src/ssh_sftpd.erl b/lib/ssh/src/ssh_sftpd.erl
index 7ee762dcee..278f6a9780 100644
--- a/lib/ssh/src/ssh_sftpd.erl
+++ b/lib/ssh/src/ssh_sftpd.erl
@@ -125,9 +125,9 @@ handle_ssh_msg({ssh_cm, _, {signal, _, _}}, State) ->
%% Ignore signals according to RFC 4254 section 6.9.
{ok, State};
-handle_ssh_msg({ssh_cm, _, {exit_signal, ChannelId, _, Error, _}}, State) ->
- Report = io_lib:format("Connection closed by peer ~n Error ~p~n",
- [Error]),
+handle_ssh_msg({ssh_cm, _, {exit_signal, ChannelId, Signal, Error, _}}, State) ->
+ Report = io_lib:format("Connection closed by peer signal ~p~n Error ~p~n",
+ [Signal,Error]),
error_logger:error_report(Report),
{stop, ChannelId, State};
diff --git a/lib/ssh/src/ssh_xfer.erl b/lib/ssh/src/ssh_xfer.erl
index e1680c120e..7bb9c2d101 100644
--- a/lib/ssh/src/ssh_xfer.erl
+++ b/lib/ssh/src/ssh_xfer.erl
@@ -734,7 +734,7 @@ decode_ATTR(Vsn, <<?UINT32(Flags), Tail/binary>>) ->
{Type,Tail2} =
if Vsn =< 3 ->
{?SSH_FILEXFER_TYPE_UNKNOWN, Tail};
- Vsn >= 5 ->
+ true ->
<<?BYTE(T), TL/binary>> = Tail,
{T, TL}
end,
diff --git a/lib/ssh/vsn.mk b/lib/ssh/vsn.mk
index 6060e50d31..c3572b5b70 100644
--- a/lib/ssh/vsn.mk
+++ b/lib/ssh/vsn.mk
@@ -1,5 +1,4 @@
#-*-makefile-*- ; force emacs to enter makefile-mode
SSH_VSN = 4.7
-
APP_VSN = "ssh-$(SSH_VSN)"
diff --git a/lib/stdlib/src/beam_lib.erl b/lib/stdlib/src/beam_lib.erl
index ef4c7d255c..01181b1097 100644
--- a/lib/stdlib/src/beam_lib.erl
+++ b/lib/stdlib/src/beam_lib.erl
@@ -690,30 +690,31 @@ chunk_to_data(debug_info=Id, Chunk, File, _Cs, AtomTable, Mod) ->
<<0:8,N:8,Mode0:N/binary,Rest/binary>> ->
Mode = binary_to_atom(Mode0, utf8),
Term = decrypt_chunk(Mode, Mod, File, Id, Rest),
- {AtomTable, {Id, Term}};
+ {AtomTable, {Id, anno_from_term(Term)}};
_ ->
case catch binary_to_term(Chunk) of
{'EXIT', _} ->
error({invalid_chunk, File, chunk_name_to_id(Id, File)});
Term ->
- {AtomTable, {Id, Term}}
+ {AtomTable, {Id, anno_from_term(Term)}}
end
end;
chunk_to_data(abstract_code=Id, Chunk, File, _Cs, AtomTable, Mod) ->
+ %% Before Erlang/OTP 20.0.
case Chunk of
<<>> ->
{AtomTable, {Id, no_abstract_code}};
<<0:8,N:8,Mode0:N/binary,Rest/binary>> ->
Mode = binary_to_atom(Mode0, utf8),
Term = decrypt_chunk(Mode, Mod, File, Id, Rest),
- {AtomTable, {Id, anno_from_term(Term)}};
+ {AtomTable, {Id, old_anno_from_term(Term)}};
_ ->
case catch binary_to_term(Chunk) of
{'EXIT', _} ->
error({invalid_chunk, File, chunk_name_to_id(Id, File)});
Term ->
try
- {AtomTable, {Id, anno_from_term(Term)}}
+ {AtomTable, {Id, old_anno_from_term(Term)}}
catch
_:_ ->
error({invalid_chunk, File,
@@ -947,14 +948,24 @@ decrypt_chunk(Type, Module, File, Id, Bin) ->
error({key_missing_or_invalid, File, Id})
end.
-anno_from_term({raw_abstract_v1, Forms}) ->
+old_anno_from_term({raw_abstract_v1, Forms}) ->
{raw_abstract_v1, anno_from_forms(Forms)};
-anno_from_term({Tag, Forms}) when Tag =:= abstract_v1; Tag =:= abstract_v2 ->
+old_anno_from_term({Tag, Forms}) when Tag =:= abstract_v1;
+ Tag =:= abstract_v2 ->
try {Tag, anno_from_forms(Forms)}
catch
_:_ ->
{Tag, Forms}
end;
+old_anno_from_term(T) ->
+ T.
+
+anno_from_term({debug_info_v1=Tag1, erl_abstract_code=Tag2, {Forms, Opts}}) ->
+ try {Tag1, Tag2, {anno_from_forms(Forms), Opts}}
+ catch
+ _:_ ->
+ {Tag1, Tag2, {Forms, Opts}}
+ end;
anno_from_term(T) ->
T.
diff --git a/lib/stdlib/src/erl_eval.erl b/lib/stdlib/src/erl_eval.erl
index 31c0e60fe1..2066b2f60f 100644
--- a/lib/stdlib/src/erl_eval.erl
+++ b/lib/stdlib/src/erl_eval.erl
@@ -329,7 +329,8 @@ expr({'fun',Line,{clauses,Cs}} = Ex, Bs, Lf, Ef, RBs) ->
20 -> fun (A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T) ->
eval_fun([A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T], Info) end;
_Other ->
- erlang:raise(error, {'argument_limit',{'fun',Line,Cs}},
+ L = erl_anno:location(Line),
+ erlang:raise(error, {'argument_limit',{'fun',L,to_terms(Cs)}},
?STACKTRACE)
end,
ret_expr(F, Bs, RBs);
@@ -381,7 +382,9 @@ expr({named_fun,Line,Name,Cs} = Ex, Bs, Lf, Ef, RBs) ->
eval_named_fun([A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T],
RF, Info) end;
_Other ->
- erlang:raise(error, {'argument_limit',{named_fun,Line,Name,Cs}},
+ L = erl_anno:location(Line),
+ erlang:raise(error, {'argument_limit',
+ {named_fun,L,Name,to_terms(Cs)}},
?STACKTRACE)
end,
ret_expr(F, Bs, RBs);
@@ -1092,7 +1095,7 @@ match(Pat, Term, Bs) ->
match(Pat, Term, Bs, BBs) ->
case catch match1(Pat, Term, Bs, BBs) of
invalid ->
- erlang:raise(error, {illegal_pattern,Pat}, ?STACKTRACE);
+ erlang:raise(error, {illegal_pattern,to_term(Pat)}, ?STACKTRACE);
Other ->
Other
end.
@@ -1288,6 +1291,12 @@ merge_bindings(Bs1, Bs2) ->
%% end
%% end, Bs2, Bs1).
+to_terms(Abstrs) ->
+ [to_term(Abstr) || Abstr <- Abstrs].
+
+to_term(Abstr) ->
+ erl_parse:anno_to_term(Abstr).
+
%% Substitute {value, A, Item} for {var, A, Var}, preserving A.
%% {value, A, Item} is a shell/erl_eval convention, and for example
%% the linter cannot handle it.
diff --git a/lib/stdlib/src/erl_parse.yrl b/lib/stdlib/src/erl_parse.yrl
index 3390cee8ae..9602f0bcd9 100644
--- a/lib/stdlib/src/erl_parse.yrl
+++ b/lib/stdlib/src/erl_parse.yrl
@@ -980,7 +980,7 @@ Erlang code.
-type af_unary_op(T) :: {'op', anno(), unary_op(), T}.
--type unary_op() :: '+' | '*' | 'bnot' | 'not'.
+-type unary_op() :: '+' | '-' | 'bnot' | 'not'.
%% See also lib/stdlib/{src/erl_bits.erl,include/erl_bits.hrl}.
-type type_specifier_list() :: 'default' | [type_specifier(), ...].
diff --git a/lib/stdlib/src/erl_pp.erl b/lib/stdlib/src/erl_pp.erl
index 367dbefb82..dd302a2880 100644
--- a/lib/stdlib/src/erl_pp.erl
+++ b/lib/stdlib/src/erl_pp.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2018. 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.
@@ -59,7 +59,7 @@
_ -> ?TEST(T)
end).
-define(EXPRS_TEST(L),
- [?TEST(E) || E <- L]).
+ _ = [?TEST(E) || E <- L]).
-define(TEST(T),
%% Assumes that erl_anno has been compiled with DEBUG=true.
%% erl_pp does not use the annoations, but test it anyway.
diff --git a/lib/stdlib/test/beam_lib_SUITE.erl b/lib/stdlib/test/beam_lib_SUITE.erl
index 73219f8fd8..3597d6d94b 100644
--- a/lib/stdlib/test/beam_lib_SUITE.erl
+++ b/lib/stdlib/test/beam_lib_SUITE.erl
@@ -78,7 +78,7 @@ normal(Conf) when is_list(Conf) ->
BeamFile = Simple ++ ".beam",
simple_file(Source),
- NoOfTables = length(ets:all()),
+ NoOfTables = erlang:system_info(ets_count),
P0 = pps(),
do_normal(Source, PrivDir, BeamFile, []),
@@ -95,7 +95,7 @@ normal(Conf) when is_list(Conf) ->
file:delete(BeamFile),
file:delete(Source),
- NoOfTables = length(ets:all()),
+ NoOfTables = erlang:system_info(ets_count),
true = (P0 == pps()),
ok.
@@ -173,7 +173,7 @@ error(Conf) when is_list(Conf) ->
WrongFile = Simple ++ "foo.beam",
simple_file(Source),
- NoOfTables = length(ets:all()),
+ NoOfTables = erlang:system_info(ets_count),
P0 = pps(),
{ok,_} = compile:file(Source, [{outdir,PrivDir},debug_info]),
ACopy = filename:join(PrivDir, "a_copy.beam"),
@@ -213,7 +213,7 @@ error(Conf) when is_list(Conf) ->
%% we have eliminated them.
ok = file:write_file(BeamFile, <<"FOR1",5:32,"BEAMfel">>),
- NoOfTables = length(ets:all()),
+ NoOfTables = erlang:system_info(ets_count),
true = (P0 == pps()),
file:delete(Source),
file:delete(WrongFile),
@@ -273,7 +273,7 @@ cmp(Conf) when is_list(Conf) ->
{Source2D1, BeamFile2D1} = make_beam(Dir1, simple2, concat),
{SourceD2, BeamFileD2} = make_beam(Dir2, simple, concat),
- NoOfTables = length(ets:all()),
+ NoOfTables = erlang:system_info(ets_count),
P0 = pps(),
%% cmp
@@ -300,7 +300,7 @@ cmp(Conf) when is_list(Conf) ->
ver(not_a_directory, beam_lib:diff_dirs(foo, bar)),
true = (P0 == pps()),
- NoOfTables = length(ets:all()),
+ NoOfTables = erlang:system_info(ets_count),
delete_files([SourceD1, BeamFileD1, Source2D1,
BeamFile2D1, SourceD2, BeamFileD2]),
@@ -321,7 +321,7 @@ cmp_literals(Conf) when is_list(Conf) ->
{SourceD1, BeamFileD1} = make_beam(Dir1, simple, constant),
{SourceD2, BeamFileD2} = make_beam(Dir2, simple, constant2),
- NoOfTables = length(ets:all()),
+ NoOfTables = erlang:system_info(ets_count),
P0 = pps(),
%% cmp
@@ -334,7 +334,7 @@ cmp_literals(Conf) when is_list(Conf) ->
ver(chunks_different, beam_lib:cmp(B1, B2)),
true = (P0 == pps()),
- NoOfTables = length(ets:all()),
+ NoOfTables = erlang:system_info(ets_count),
delete_files([SourceD1, BeamFileD1, SourceD2, BeamFileD2]),
@@ -351,7 +351,7 @@ strip(Conf) when is_list(Conf) ->
{Source4D1, BeamFile4D1} = make_beam(PrivDir, constant, constant),
{Source5D1, BeamFile5D1} = make_beam(PrivDir, lines, lines),
- NoOfTables = length(ets:all()),
+ NoOfTables = erlang:system_info(ets_count),
P0 = pps(),
%% strip binary
@@ -392,7 +392,7 @@ strip(Conf) when is_list(Conf) ->
(catch lines:t(atom)),
true = (P0 == pps()),
- NoOfTables = length(ets:all()),
+ NoOfTables = erlang:system_info(ets_count),
delete_files([SourceD1, BeamFileD1,
Source2D1, BeamFile2D1,
@@ -457,7 +457,7 @@ building(Conf) when is_list(Conf) ->
{SourceD1, BeamFileD1} = make_beam(Dir1, building, member),
- NoOfTables = length(ets:all()),
+ NoOfTables = erlang:system_info(ets_count),
P0 = pps(),
%% read all chunks
@@ -487,7 +487,7 @@ building(Conf) when is_list(Conf) ->
end, ChunkIds),
true = (P0 == pps()),
- NoOfTables = length(ets:all()),
+ NoOfTables = erlang:system_info(ets_count),
delete_files([SourceD1, BeamFileD1, BeamFileD2]),
file:del_dir(Dir1),
@@ -535,7 +535,7 @@ encrypted_abstr_1(Conf) ->
%% Avoid getting an extra port when crypto starts erl_ddll.
erl_ddll:start(),
- NoOfTables = length(ets:all()),
+ NoOfTables = erlang:system_info(ets_count),
P0 = pps(),
Key = "#a_crypto_key",
@@ -549,7 +549,7 @@ encrypted_abstr_1(Conf) ->
ok = crypto:stop(), %To get rid of extra ets tables.
file:delete(BeamFile),
file:delete(Source),
- NoOfTables = length(ets:all()),
+ NoOfTables = erlang:system_info(ets_count),
true = (P0 == pps()),
ok.
@@ -658,7 +658,7 @@ encrypted_abstr_file_1(Conf) ->
%% Avoid getting an extra port when crypto starts erl_ddll.
erl_ddll:start(),
- NoOfTables = length(ets:all()),
+ NoOfTables = erlang:system_info(ets_count),
P0 = pps(),
Key = "Long And niCe 99Krypto Key",
@@ -676,7 +676,7 @@ encrypted_abstr_file_1(Conf) ->
file:delete(filename:join(PrivDir, ".erlang.crypt")),
file:delete(BeamFile),
file:delete(Source),
- NoOfTables = length(ets:all()),
+ NoOfTables = erlang:system_info(ets_count),
true = (P0 == pps()),
ok.
diff --git a/lib/syntax_tools/doc/src/notes.xml b/lib/syntax_tools/doc/src/notes.xml
index 7ba90a6495..76c2d6ecbd 100644
--- a/lib/syntax_tools/doc/src/notes.xml
+++ b/lib/syntax_tools/doc/src/notes.xml
@@ -33,29 +33,28 @@
application.</p>
<section><title>Syntax_Tools 2.1.5</title>
-
- <section><title>Fixed Bugs and Malfunctions</title>
+ <section><title>Improvements and New Features</title>
<list>
<item>
- <p> Fix a bug regarding reverting map types. </p>
<p>
- Own Id: OTP-15098 Aux Id: ERIERL-177 </p>
+ Update to use the new string api instead of the old.</p>
+ <p>
+ Own Id: OTP-15036</p>
</item>
</list>
</section>
+</section>
-
- <section><title>Improvements and New Features</title>
+<section><title>Syntax_Tools 2.1.4.1</title>
+ <section><title>Fixed Bugs and Malfunctions</title>
<list>
<item>
+ <p> Fix a bug regarding reverting map types. </p>
<p>
- Update to use the new string api instead of the old.</p>
- <p>
- Own Id: OTP-15036</p>
+ Own Id: OTP-15098 Aux Id: ERIERL-177 </p>
</item>
</list>
</section>
-
</section>
<section><title>Syntax_Tools 2.1.4</title>
diff --git a/lib/syntax_tools/src/erl_syntax.erl b/lib/syntax_tools/src/erl_syntax.erl
index 029f1e88ac..758aff32fd 100644
--- a/lib/syntax_tools/src/erl_syntax.erl
+++ b/lib/syntax_tools/src/erl_syntax.erl
@@ -7223,7 +7223,7 @@ macro_arguments(Node) ->
%% @doc Returns the syntax tree corresponding to an Erlang term.
%% `Term' must be a literal term, i.e., one that can be
%% represented as a source code literal. Thus, it may not contain a
-%% process identifier, port, reference, binary or function value as a
+%% process identifier, port, reference or function value as a
%% subterm. The function recognises printable strings, in order to get a
%% compact and readable representation. Evaluation fails with reason
%% `badarg' if `Term' is not a literal term.
@@ -7257,6 +7257,13 @@ abstract(T) when is_map(T) ->
|| {Key,Value} <- maps:to_list(T)]);
abstract(T) when is_binary(T) ->
binary([binary_field(integer(B)) || B <- binary_to_list(T)]);
+abstract(T) when is_bitstring(T) ->
+ S = bit_size(T),
+ ByteS = S div 8,
+ BitS = S rem 8,
+ <<Bin:ByteS/binary, I:BitS>> = T,
+ binary([binary_field(integer(B)) || B <- binary_to_list(Bin)]
+ ++ [binary_field(integer(I), integer(BitS), [])]);
abstract(T) ->
erlang:error({badarg, T}).
@@ -7332,15 +7339,20 @@ concrete(Node) ->
Node0 -> maps:merge(concrete(Node0),M0)
end;
binary ->
- Fs = [revert_binary_field(
- binary_field(binary_field_body(F),
- case binary_field_size(F) of
- none -> none;
- S ->
- revert(S)
- end,
- binary_field_types(F)))
- || F <- binary_fields(Node)],
+ Fs = [begin
+ B = binary_field_body(F),
+ {Body, Size} =
+ case type(B) of
+ size_qualifier ->
+ {size_qualifier_body(B),
+ size_qualifier_argument(B)};
+ _ ->
+ {B, none}
+ end,
+ revert_binary_field(
+ binary_field(Body, Size, binary_field_types(F)))
+ end
+ || F <- binary_fields(Node)],
{value, B, _} =
eval_bits:expr_grp(Fs, [],
fun(F, _) ->
@@ -7413,7 +7425,14 @@ is_literal(T) ->
is_literal_binary_field(F) ->
case binary_field_types(F) of
- [] -> is_literal(binary_field_body(F));
+ [] -> B = binary_field_body(F),
+ case type(B) of
+ size_qualifier ->
+ is_literal(size_qualifier_body(B)) andalso
+ is_literal(size_qualifier_argument(B));
+ _ ->
+ is_literal(B)
+ end;
_ -> false
end.
diff --git a/lib/syntax_tools/test/syntax_tools_SUITE.erl b/lib/syntax_tools/test/syntax_tools_SUITE.erl
index c8e6448d37..4cddf8f0c3 100644
--- a/lib/syntax_tools/test/syntax_tools_SUITE.erl
+++ b/lib/syntax_tools/test/syntax_tools_SUITE.erl
@@ -157,6 +157,7 @@ t_abstract_type(Config) when is_list(Config) ->
{[$a,$b,$c],string},
{"hello world",string},
{<<1,2,3>>,binary},
+ {<<1,2,3:4>>,binary},
{#{a=>1,"b"=>2},map_expr},
{#{#{i=>1}=>1,"b"=>#{v=>2}},map_expr},
{{a,b,c},tuple}]),
diff --git a/lib/tools/test/xref_SUITE.erl b/lib/tools/test/xref_SUITE.erl
index 018f632948..4ec75f7962 100644
--- a/lib/tools/test/xref_SUITE.erl
+++ b/lib/tools/test/xref_SUITE.erl
@@ -2233,18 +2233,18 @@ variables(Conf) when is_list(Conf) ->
{{error, _, _}, _} = xref_base:variables(S108, [{verbose,false}]),
{ok, S109} = xref_base:set_library_path(S108, [], [{verbose,false}]),
- Tabs = length(ets:all()),
+ NoOfTables = erlang:system_info(ets_count),
{ok, S110} = eval("Eplus := closure E, TT := Eplus",
'closure()', S109),
{{ok, [{user, ['Eplus','TT']}]}, S111} = xref_base:variables(S110),
{ok, S112} = xref_base:forget(S111, ['TT','Eplus']),
- true = Tabs =:= length(ets:all()),
+ true = NoOfTables =:= erlang:system_info(ets_count),
{ok, NS0} = eval("Eplus := closure E", 'closure()', S112),
{{ok, [{user, ['Eplus']}]}, NS} = xref_base:variables(NS0),
ok = xref_base:delete(NS),
- true = Tabs =:= length(ets:all()),
+ true = NoOfTables =:= erlang:system_info(ets_count),
ok = file:delete(Beam),
ok.
diff --git a/otp_versions.table b/otp_versions.table
index aba60a6a5f..a76577c819 100644
--- a/otp_versions.table
+++ b/otp_versions.table
@@ -1,6 +1,8 @@
OTP-21.0.2 : compiler-7.2.2 erts-10.0.2 public_key-1.6.1 stdlib-3.5.1 # asn1-5.0.6 common_test-1.16 crypto-4.3 debugger-4.2.5 dialyzer-3.3 diameter-2.1.5 edoc-0.9.3 eldap-1.2.4 erl_docgen-0.8 erl_interface-3.10.3 et-1.6.2 eunit-2.3.6 ftp-1.0 hipe-3.18 inets-7.0 jinterface-1.9 kernel-6.0 megaco-3.18.3 mnesia-4.15.4 observer-2.8 odbc-2.12.1 os_mon-2.4.5 otp_mibs-1.2 parsetools-2.1.7 reltool-0.7.6 runtime_tools-1.13 sasl-3.2 snmp-5.2.11 ssh-4.7 ssl-9.0 syntax_tools-2.1.5 tftp-1.0 tools-3.0 wx-1.8.4 xmerl-1.3.17 :
OTP-21.0.1 : compiler-7.2.1 erts-10.0.1 # asn1-5.0.6 common_test-1.16 crypto-4.3 debugger-4.2.5 dialyzer-3.3 diameter-2.1.5 edoc-0.9.3 eldap-1.2.4 erl_docgen-0.8 erl_interface-3.10.3 et-1.6.2 eunit-2.3.6 ftp-1.0 hipe-3.18 inets-7.0 jinterface-1.9 kernel-6.0 megaco-3.18.3 mnesia-4.15.4 observer-2.8 odbc-2.12.1 os_mon-2.4.5 otp_mibs-1.2 parsetools-2.1.7 public_key-1.6 reltool-0.7.6 runtime_tools-1.13 sasl-3.2 snmp-5.2.11 ssh-4.7 ssl-9.0 stdlib-3.5 syntax_tools-2.1.5 tftp-1.0 tools-3.0 wx-1.8.4 xmerl-1.3.17 :
OTP-21.0 : asn1-5.0.6 common_test-1.16 compiler-7.2 crypto-4.3 debugger-4.2.5 dialyzer-3.3 diameter-2.1.5 edoc-0.9.3 eldap-1.2.4 erl_docgen-0.8 erl_interface-3.10.3 erts-10.0 et-1.6.2 eunit-2.3.6 ftp-1.0 hipe-3.18 inets-7.0 jinterface-1.9 kernel-6.0 mnesia-4.15.4 observer-2.8 os_mon-2.4.5 otp_mibs-1.2 parsetools-2.1.7 public_key-1.6 reltool-0.7.6 runtime_tools-1.13 sasl-3.2 ssh-4.7 ssl-9.0 stdlib-3.5 syntax_tools-2.1.5 tftp-1.0 tools-3.0 wx-1.8.4 xmerl-1.3.17 # megaco-3.18.3 odbc-2.12.1 snmp-5.2.11 :
+OTP-20.3.8.2 : erl_interface-3.10.2.1 erts-9.3.3.1 ic-4.4.4.1 kernel-5.4.3.1 # asn1-5.0.5 common_test-1.15.4 compiler-7.1.5 cosEvent-2.2.2 cosEventDomain-1.2.2 cosFileTransfer-1.2.2 cosNotification-1.2.3 cosProperty-1.2.3 cosTime-1.2.3 cosTransactions-1.3.3 crypto-4.2.2 debugger-4.2.4 dialyzer-3.2.4 diameter-2.1.4 edoc-0.9.2 eldap-1.2.3 erl_docgen-0.7.3 et-1.6.1 eunit-2.3.5 hipe-3.17.1 inets-6.5.2.1 jinterface-1.8.1 megaco-3.18.3 mnesia-4.15.3 observer-2.7 odbc-2.12.1 orber-3.8.4 os_mon-2.4.4 otp_mibs-1.1.2 parsetools-2.1.6 public_key-1.5.2 reltool-0.7.5 runtime_tools-1.12.5 sasl-3.1.2 snmp-5.2.11 ssh-4.6.9.1 ssl-8.2.6 stdlib-3.4.5 syntax_tools-2.1.4.1 tools-2.11.2 wx-1.8.3 xmerl-1.3.16 :
+OTP-20.3.8.1 : inets-6.5.2.1 ssh-4.6.9.1 syntax_tools-2.1.4.1 # asn1-5.0.5 common_test-1.15.4 compiler-7.1.5 cosEvent-2.2.2 cosEventDomain-1.2.2 cosFileTransfer-1.2.2 cosNotification-1.2.3 cosProperty-1.2.3 cosTime-1.2.3 cosTransactions-1.3.3 crypto-4.2.2 debugger-4.2.4 dialyzer-3.2.4 diameter-2.1.4 edoc-0.9.2 eldap-1.2.3 erl_docgen-0.7.3 erl_interface-3.10.2 erts-9.3.3 et-1.6.1 eunit-2.3.5 hipe-3.17.1 ic-4.4.4 jinterface-1.8.1 kernel-5.4.3 megaco-3.18.3 mnesia-4.15.3 observer-2.7 odbc-2.12.1 orber-3.8.4 os_mon-2.4.4 otp_mibs-1.1.2 parsetools-2.1.6 public_key-1.5.2 reltool-0.7.5 runtime_tools-1.12.5 sasl-3.1.2 snmp-5.2.11 ssl-8.2.6 stdlib-3.4.5 tools-2.11.2 wx-1.8.3 xmerl-1.3.16 :
OTP-20.3.8 : erts-9.3.3 snmp-5.2.11 # asn1-5.0.5 common_test-1.15.4 compiler-7.1.5 cosEvent-2.2.2 cosEventDomain-1.2.2 cosFileTransfer-1.2.2 cosNotification-1.2.3 cosProperty-1.2.3 cosTime-1.2.3 cosTransactions-1.3.3 crypto-4.2.2 debugger-4.2.4 dialyzer-3.2.4 diameter-2.1.4 edoc-0.9.2 eldap-1.2.3 erl_docgen-0.7.3 erl_interface-3.10.2 et-1.6.1 eunit-2.3.5 hipe-3.17.1 ic-4.4.4 inets-6.5.2 jinterface-1.8.1 kernel-5.4.3 megaco-3.18.3 mnesia-4.15.3 observer-2.7 odbc-2.12.1 orber-3.8.4 os_mon-2.4.4 otp_mibs-1.1.2 parsetools-2.1.6 public_key-1.5.2 reltool-0.7.5 runtime_tools-1.12.5 sasl-3.1.2 ssh-4.6.9 ssl-8.2.6 stdlib-3.4.5 syntax_tools-2.1.4 tools-2.11.2 wx-1.8.3 xmerl-1.3.16 :
OTP-20.3.7 : erl_docgen-0.7.3 erts-9.3.2 inets-6.5.2 # asn1-5.0.5 common_test-1.15.4 compiler-7.1.5 cosEvent-2.2.2 cosEventDomain-1.2.2 cosFileTransfer-1.2.2 cosNotification-1.2.3 cosProperty-1.2.3 cosTime-1.2.3 cosTransactions-1.3.3 crypto-4.2.2 debugger-4.2.4 dialyzer-3.2.4 diameter-2.1.4 edoc-0.9.2 eldap-1.2.3 erl_interface-3.10.2 et-1.6.1 eunit-2.3.5 hipe-3.17.1 ic-4.4.4 jinterface-1.8.1 kernel-5.4.3 megaco-3.18.3 mnesia-4.15.3 observer-2.7 odbc-2.12.1 orber-3.8.4 os_mon-2.4.4 otp_mibs-1.1.2 parsetools-2.1.6 public_key-1.5.2 reltool-0.7.5 runtime_tools-1.12.5 sasl-3.1.2 snmp-5.2.10 ssh-4.6.9 ssl-8.2.6 stdlib-3.4.5 syntax_tools-2.1.4 tools-2.11.2 wx-1.8.3 xmerl-1.3.16 :
OTP-20.3.6 : crypto-4.2.2 ssh-4.6.9 # asn1-5.0.5 common_test-1.15.4 compiler-7.1.5 cosEvent-2.2.2 cosEventDomain-1.2.2 cosFileTransfer-1.2.2 cosNotification-1.2.3 cosProperty-1.2.3 cosTime-1.2.3 cosTransactions-1.3.3 debugger-4.2.4 dialyzer-3.2.4 diameter-2.1.4 edoc-0.9.2 eldap-1.2.3 erl_docgen-0.7.2 erl_interface-3.10.2 erts-9.3.1 et-1.6.1 eunit-2.3.5 hipe-3.17.1 ic-4.4.4 inets-6.5.1 jinterface-1.8.1 kernel-5.4.3 megaco-3.18.3 mnesia-4.15.3 observer-2.7 odbc-2.12.1 orber-3.8.4 os_mon-2.4.4 otp_mibs-1.1.2 parsetools-2.1.6 public_key-1.5.2 reltool-0.7.5 runtime_tools-1.12.5 sasl-3.1.2 snmp-5.2.10 ssl-8.2.6 stdlib-3.4.5 syntax_tools-2.1.4 tools-2.11.2 wx-1.8.3 xmerl-1.3.16 :
diff --git a/scripts/build-otp b/scripts/build-otp
index e33bf95286..c38d2c98de 100755
--- a/scripts/build-otp
+++ b/scripts/build-otp
@@ -57,23 +57,23 @@ if [ "$1" = "docs" ]; then
do_and_log "Linting documentation" make xmllint
# The code below prepares this build to be used as a deploy to
# github pages for documentation.
- # if [ "$TRAVIS_PULL_REQUEST" = "false" -a "$TRAVIS_TAG" = "" ]; then
- # set -x
- # rm -rf logs
- # SHA=`git rev-parse --verify HEAD`
- # DATE=`date -Iseconds`
- # git clean -xfdq -e $DOC_TARGET
- # git fetch https://github.com/$TRAVIS_REPO_SLUG gh-pages
- # git checkout -f FETCH_HEAD
- # rm -rf _docs/$DOC_TARGET
- # mv $DOC_TARGET _docs/$DOC_TARGET
- # echo "---" > _docs/$DOC_TARGET.md
- # echo "title: $DOC_TARGET" >> _docs/$DOC_TARGET.md
- # echo "sha: $SHA" >> _docs/$DOC_TARGET.md
- # echo "generated: $DATE" >> _docs/$DOC_TARGET.md
- # echo "---" >> _docs/$DOC_TARGET.md
- # set +x
- # fi
+ if [ "$TRAVIS_PULL_REQUEST" = "false" -a "$TRAVIS_TAG" = "" ]; then
+ set -x
+ rm -rf logs
+ SHA=`git rev-parse --verify HEAD`
+ DATE=`git show -s --format=%ci`
+ git clean -xfdq -e $DOC_TARGET
+ git fetch https://github.com/erlang/cd master
+ git checkout -f FETCH_HEAD
+ rm -rf _docs/$DOC_TARGET
+ mv $DOC_TARGET _docs/$DOC_TARGET
+ echo "---" > _docs/$DOC_TARGET.md
+ echo "title: $DOC_TARGET" >> _docs/$DOC_TARGET.md
+ echo "sha: $SHA" >> _docs/$DOC_TARGET.md
+ echo "generated: $DATE" >> _docs/$DOC_TARGET.md
+ echo "---" >> _docs/$DOC_TARGET.md
+ set +x
+ fi
fi
exit 0
diff --git a/scripts/pre-push b/scripts/pre-push
index 0349378056..71e9fd1e75 100755
--- a/scripts/pre-push
+++ b/scripts/pre-push
@@ -22,15 +22,30 @@
# <local ref> <local sha1> <remote ref> <remote sha1>
#
-RELEASES="20 19 18 17 r16 r15 r14 r13"
+NEW_RELEASES="21 20 19 18 17"
+OLD_RELEASES="r16 r15 r14 r13"
+RELEASES="$NEW_RELEASES $OLD_RELEASES"
# First commit on master, not allowed in other branches
-MASTER_ONLY=f52748254f17ba42e344798e8c787a1e3361fa33
+MASTER_ONLY=aea2a053e28a11497796879715be29ab0c3cd1a0
# Number of commits and files allowed in one push by this script
NCOMMITS_MAX=100
NFILES_MAX=100
+
+# Example testing this script for "git push upstream OTP-20.3.8.2":
+#
+#> null=0000000000000000000000000000000000000000
+#> echo "refs/tags/OTP-20.3.8.2 dummysha refs/tags/OTP-20.3.8.2 $null" | scripts/pre-push upstream https://github.com/erlang/otp.git
+
+# Example to test "git push upstream master"
+#
+#> local_sha=`git rev-parse master`
+#> remote_sha=`git rev-parse upstream/master`
+#> echo "refs/heads/master $local_sha refs/heads/master $remote_sha" | scripts/pre-push upstream https://github.com/erlang/otp.git
+
+
remote="$1"
url="$2"
@@ -158,8 +173,24 @@ then
exit 1
fi
;;
- refs/tags/OTP-20.* | refs/tags/OTP-19.* | refs/tags/OTP-18.* | refs/tags/OTP-17.*)
+ refs/tags/OTP-*)
tag=${remote_ref#refs/tags/}
+ REL="UNKNOWN"
+ for x in $NEW_RELEASES; do
+ if [ ${tag#OTP-$x.} != $tag ]
+ then
+ REL=$x
+ break
+ fi
+ done
+ if [ $REL = "UNKNOWN" ]
+ then
+ echo "$0 says:"
+ echo "***"
+ echo "*** Unknown OTP release number in tag '$tag'"
+ echo "***"
+ exit 1
+ fi
if [ "$remote_sha" != $null ]
then
echo "$0 says:"
diff --git a/system/doc/design_principles/statem.xml b/system/doc/design_principles/statem.xml
index 80ee9c992f..16a901b3a5 100644
--- a/system/doc/design_principles/statem.xml
+++ b/system/doc/design_principles/statem.xml
@@ -956,14 +956,14 @@ callback_mode() ->
<seealso marker="stdlib:gen_statem#cast/2"><c>gen_statem:cast/2</c></seealso>:
</p>
<code type="erl"><![CDATA[
-button(Digit) ->
- gen_statem:cast(?NAME, {button,Digit}).
+button(Button) ->
+ gen_statem:cast(?NAME, {button,Button}).
]]></code>
<p>
The first argument is the name of the <c>gen_statem</c> and must
agree with the name used to start it. So, we use the
same macro <c>?NAME</c> as when starting.
- <c>{button,Digit}</c> is the event content.
+ <c>{button,Button}</c> is the event content.
</p>
<p>
The event is sent to the <c>gen_statem</c>.
@@ -1171,7 +1171,7 @@ open(...) -> ... ;
callback_mode() ->
handle_event_function.
-handle_event(cast, {button,Digit}, State, #{code := Code} = Data) ->
+handle_event(cast, {button,Button}, State, #{code := Code} = Data) ->
case State of
locked ->
#{length := Length, buttons := Buttons} = Data,
@@ -1305,7 +1305,7 @@ stop() ->
locked(timeout, _, Data) ->
{next_state, locked, Data#{buttons := []}};
locked(
- cast, {button,Digit},
+ cast, {button,Button},
#{code := Code, length := Length, buttons := Buttons} = Data) ->
...
true -> % Incomplete | Incorrect
@@ -1364,7 +1364,7 @@ locked(
<code type="erl"><![CDATA[
...
locked(
- cast, {button,Digit},
+ cast, {button,Button},
#{code := Code, length := Length, buttons := Buttons} = Data) ->
...
if
@@ -1421,7 +1421,7 @@ open(cast, {button,_}, Data) ->
<code type="erl"><![CDATA[
...
locked(
- cast, {button,Digit},
+ cast, {button,Button},
#{code := Code, length := Length, buttons := Buttons} = Data) ->
...
if
@@ -1662,7 +1662,7 @@ locked(enter, _OldState, Data) ->
do_lock(),
{keep_state,Data#{buttons => []}};
locked(
- cast, {button,Digit},
+ cast, {button,Button},
#{code := Code, length := Length, buttons := Buttons} = Data) ->
...
if
@@ -1747,7 +1747,7 @@ open(state_timeout, lock, Data) ->
</p>
<code type="erl"><![CDATA[
...
--export(down/1, up/1).
+-export([down/1, up/1]).
...
down(Button) ->
gen_statem:cast(?NAME, {down,Button}).
@@ -1759,15 +1759,15 @@ up(Button) ->
locked(enter, _OldState, Data) ->
do_lock(),
- {keep_state,Data#{remaining => Code, buf => []}};
+ {keep_state,Data#{buttons => []}};
locked(
- internal, {button,Digit},
+ internal, {button,Button},
#{code := Code, length := Length, buttons := Buttons} = Data) ->
...
]]></code>
<code type="erl"><![CDATA[
handle_common(cast, {down,Button}, Data) ->
- {keep_state, Data#{button := Button}};
+ {keep_state, Data#{button => Button}};
handle_common(cast, {up,Button}, Data) ->
case Data of
#{button := Button} ->
@@ -1833,10 +1833,10 @@ start_link(Code) ->
stop() ->
gen_statem:stop(?NAME).
-down(Digit) ->
- gen_statem:cast(?NAME, {down,Digit}).
-up(Digit) ->
- gen_statem:cast(?NAME, {up,Digit}).
+down(Button) ->
+ gen_statem:cast(?NAME, {down,Button}).
+up(Button) ->
+ gen_statem:cast(?NAME, {up,Button}).
code_length() ->
gen_statem:call(?NAME, code_length).
]]></code>
@@ -1873,7 +1873,7 @@ locked(enter, _OldState, Data) ->
locked(state_timeout, button, Data) ->
{keep_state, Data#{buttons := []}};
locked(
- internal, {button,Digit},
+ internal, {button,Button},
#{code := Code, length := Length, buttons := Buttons} = Data) ->
NewButtons =
if
@@ -1884,7 +1884,6 @@ locked(
end ++ [Button],
if
NewButtons =:= Code -> % Correct
- do_unlock(),
{next_state, open, Data};
true -> % Incomplete | Incorrect
{keep_state, Data#{buttons := NewButtons},
@@ -1940,7 +1939,7 @@ handle_event(enter, _OldState, locked, Data) ->
handle_event(state_timeout, button, locked, Data) ->
{keep_state, Data#{buttons := []}};
handle_event(
- internal, {button,Digit}, locked,
+ internal, {button,Button}, locked,
#{code := Code, length := Length, buttons := Buttons} = Data) ->
NewButtons =
if
@@ -1951,7 +1950,6 @@ handle_event(
end ++ [Button],
if
NewButtons =:= Code -> % Correct
- do_unlock(),
{next_state, open, Data};
true -> % Incomplete | Incorrect
{keep_state, Data#{buttons := NewButtons},
@@ -2152,7 +2150,7 @@ handle_event(enter, _OldState, {locked,_}, Data) ->
handle_event(state_timeout, button, {locked,_}, Data) ->
{keep_state, Data#{buttons := []}};
handle_event(
- cast, {button,Digit}, {locked,LockButton},
+ cast, {button,Button}, {locked,LockButton},
#{code := Code, length := Length, buttons := Buttons} = Data) ->
NewButtons =
if
@@ -2163,7 +2161,6 @@ handle_event(
end ++ [Button],
if
NewButtons =:= Code -> % Correct
- do_unlock(),
{next_state, {open,LockButton}, Data};
true -> % Incomplete | Incorrect
{keep_state, Data#{buttons := NewButtons},
@@ -2177,11 +2174,11 @@ handle_event(enter, _OldState, {open,_}, _Data) ->
do_unlock(),
{keep_state_and_data,
[{state_timeout,10000,lock}]}; % Time in milliseconds
-handle_event(state_timeout, lock, {open,_}, Data) ->
- {next_state, locked, Data};
+handle_event(state_timeout, lock, {open,LockButton}, Data) ->
+ {next_state, {locked,LockButton}, Data};
handle_event(cast, {button,LockButton}, {open,LockButton}, Data) ->
{next_state, {locked,LockButton}, Data};
-handle_event(cast, {button,_}, {open,_}, Data) ->
+handle_event(cast, {button,_}, {open,_}, _Data) ->
{keep_state_and_data,[postpone]};
]]></code>
<code type="erl"><![CDATA[