aboutsummaryrefslogtreecommitdiffstats
path: root/erts
diff options
context:
space:
mode:
Diffstat (limited to 'erts')
-rw-r--r--erts/doc/src/erlang.xml102
-rw-r--r--erts/emulator/beam/erl_bif_binary.c22
-rw-r--r--erts/emulator/drivers/common/inet_drv.c4
-rw-r--r--erts/emulator/test/port_SUITE.erl10
-rw-r--r--erts/emulator/test/port_SUITE_data/Makefile.src2
-rw-r--r--erts/emulator/test/port_SUITE_data/dead_port.c102
-rw-r--r--erts/preloaded/ebin/erl_prim_loader.beambin50392 -> 50384 bytes
-rw-r--r--erts/preloaded/ebin/erlang.beambin24324 -> 24316 bytes
-rw-r--r--erts/preloaded/ebin/init.beambin44352 -> 44348 bytes
-rw-r--r--erts/preloaded/ebin/otp_ring0.beambin1436 -> 1428 bytes
-rw-r--r--erts/preloaded/ebin/prim_file.beambin30544 -> 30536 bytes
-rw-r--r--erts/preloaded/ebin/prim_inet.beambin57280 -> 57268 bytes
-rw-r--r--erts/preloaded/ebin/prim_zip.beambin22440 -> 22428 bytes
-rw-r--r--erts/preloaded/ebin/zlib.beambin10620 -> 10612 bytes
-rw-r--r--erts/test/Makefile9
-rw-r--r--erts/test/autoimport_SUITE.erl163
-rw-r--r--erts/test/autoimport_SUITE_data/dummy.txt19
17 files changed, 368 insertions, 65 deletions
diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml
index ba93fe34d3..59ac3dc66c 100644
--- a/erts/doc/src/erlang.xml
+++ b/erts/doc/src/erlang.xml
@@ -80,7 +80,7 @@ iolist() = [char() | binary() | iolist()]
</desc>
</func>
<func>
- <name>adler32(Data) -> int()</name>
+ <name>erlang:adler32(Data) -> int()</name>
<fsummary>Compute adler32 checksum</fsummary>
<type>
<v>Data = iodata()</v>
@@ -90,7 +90,7 @@ iolist() = [char() | binary() | iolist()]
</desc>
</func>
<func>
- <name>adler32(OldAdler, Data) -> int()</name>
+ <name>erlang:adler32(OldAdler, Data) -> int()</name>
<fsummary>Compute adler32 checksum</fsummary>
<type>
<v>OldAdler = int()</v>
@@ -102,17 +102,17 @@ iolist() = [char() | binary() | iolist()]
<c>Data</c>.</p>
<p>The following code:</p>
<code>
- X = adler32(Data1),
- Y = adler32(X,Data2).
+ X = erlang:adler32(Data1),
+ Y = erlang:adler32(X,Data2).
</code>
<p>- would assign the same value to <c>Y</c> as this would:</p>
<code>
- Y = adler32([Data1,Data2]).
+ Y = erlang:adler32([Data1,Data2]).
</code>
</desc>
</func>
<func>
- <name>adler32_combine(FirstAdler, SecondAdler, SecondSize) -> int()</name>
+ <name>erlang:adler32_combine(FirstAdler, SecondAdler, SecondSize) -> int()</name>
<fsummary>Combine two adler32 checksums</fsummary>
<type>
<v>FirstAdler = SecondAdler = int()</v>
@@ -124,14 +124,14 @@ iolist() = [char() | binary() | iolist()]
the second checksum to be known.</p>
<p>The following code:</p>
<code>
- Y = adler32(Data1),
- Z = adler32(Y,Data2).
+ Y = erlang:adler32(Data1),
+ Z = erlang:adler32(Y,Data2).
</code>
<p>- would assign the same value to <c>Z</c> as this would:</p>
<code>
- X = adler32(Data1),
- Y = adler32(Data2),
- Z = adler32_combine(X,Y,iolist_size(Data2)).
+ X = erlang:adler32(Data1),
+ Y = erlang:adler32(Data2),
+ Z = erlang:adler32_combine(X,Y,iolist_size(Data2)).
</code>
</desc>
</func>
@@ -553,7 +553,7 @@ false</pre>
</desc>
</func>
<func>
- <name>crc32(Data) -> int()</name>
+ <name>erlang:crc32(Data) -> int()</name>
<fsummary>Compute crc32 (IEEE 802.3) checksum</fsummary>
<type>
<v>Data = iodata()</v>
@@ -563,7 +563,7 @@ false</pre>
</desc>
</func>
<func>
- <name>crc32(OldCrc, Data) -> int()</name>
+ <name>erlang:crc32(OldCrc, Data) -> int()</name>
<fsummary>Compute crc32 (IEEE 802.3) checksum</fsummary>
<type>
<v>OldCrc = int()</v>
@@ -575,17 +575,17 @@ false</pre>
<c>Data</c>.</p>
<p>The following code:</p>
<code>
- X = crc32(Data1),
- Y = crc32(X,Data2).
+ X = erlang:crc32(Data1),
+ Y = erlang:crc32(X,Data2).
</code>
<p>- would assign the same value to <c>Y</c> as this would:</p>
<code>
- Y = crc32([Data1,Data2]).
+ Y = erlang:crc32([Data1,Data2]).
</code>
</desc>
</func>
<func>
- <name>crc32_combine(FirstCrc, SecondCrc, SecondSize) -> int()</name>
+ <name>erlang:crc32_combine(FirstCrc, SecondCrc, SecondSize) -> int()</name>
<fsummary>Combine two crc32 (IEEE 802.3) checksums</fsummary>
<type>
<v>FirstCrc = SecondCrc = int()</v>
@@ -597,14 +597,14 @@ false</pre>
the second checksum to be known.</p>
<p>The following code:</p>
<code>
- Y = crc32(Data1),
- Z = crc32(Y,Data2).
+ Y = erlang:crc32(Data1),
+ Z = erlang:crc32(Y,Data2).
</code>
<p>- would assign the same value to <c>Z</c> as this would:</p>
<code>
- X = crc32(Data1),
- Y = crc32(Data2),
- Z = crc32_combine(X,Y,iolist_size(Data2)).
+ X = erlang:crc32(Data1),
+ Y = erlang:crc32(Data2),
+ Z = erlang:crc32_combine(X,Y,iolist_size(Data2)).
</code>
</desc>
</func>
@@ -624,7 +624,7 @@ false</pre>
</desc>
</func>
<func>
- <name>decode_packet(Type,Bin,Options) -> {ok,Packet,Rest} | {more,Length} | {error,Reason}</name>
+ <name>erlang:decode_packet(Type,Bin,Options) -> {ok,Packet,Rest} | {more,Length} | {error,Reason}</name>
<fsummary>Extracts a protocol packet from a binary</fsummary>
<type>
<v>Bin = binary()</v>
@@ -760,7 +760,7 @@ false</pre>
</desc>
</func>
<func>
- <name>erlang:demonitor(MonitorRef) -> true</name>
+ <name>demonitor(MonitorRef) -> true</name>
<fsummary>Stop monitoring</fsummary>
<type>
<v>MonitorRef = reference()</v>
@@ -768,10 +768,10 @@ false</pre>
<desc>
<p>If <c>MonitorRef</c> is a reference which the calling process
obtained by calling
- <seealso marker="#monitor/2">erlang:monitor/2</seealso>,
+ <seealso marker="#monitor/2">monitor/2</seealso>,
this monitoring is turned off. If the monitoring is already
turned off, nothing happens.</p>
- <p>Once <c>erlang:demonitor(MonitorRef)</c> has returned it is
+ <p>Once <c>demonitor(MonitorRef)</c> has returned it is
guaranteed that no <c>{'DOWN', MonitorRef, _, _, _}</c> message
due to the monitor will be placed in the callers message queue
in the future. A <c>{'DOWN', MonitorRef, _, _, _}</c> message
@@ -779,10 +779,10 @@ false</pre>
the call, though. Therefore, in most cases, it is advisable
to remove such a <c>'DOWN'</c> message from the message queue
after monitoring has been stopped.
- <seealso marker="#demonitor/2">erlang:demonitor(MonitorRef, [flush])</seealso> can be used instead of
- <c>erlang:demonitor(MonitorRef)</c> if this cleanup is wanted.</p>
+ <seealso marker="#demonitor/2">demonitor(MonitorRef, [flush])</seealso> can be used instead of
+ <c>demonitor(MonitorRef)</c> if this cleanup is wanted.</p>
<note>
- <p>Prior to OTP release R11B (erts version 5.5) <c>erlang:demonitor/1</c>
+ <p>Prior to OTP release R11B (erts version 5.5) <c>demonitor/1</c>
behaved completely asynchronous, i.e., the monitor was active
until the "demonitor signal" reached the monitored entity. This
had one undesirable effect, though. You could never know when
@@ -800,7 +800,7 @@ false</pre>
</desc>
</func>
<func>
- <name>erlang:demonitor(MonitorRef, OptionList) -> true|false</name>
+ <name>demonitor(MonitorRef, OptionList) -> true|false</name>
<fsummary>Stop monitoring</fsummary>
<type>
<v>MonitorRef = reference()</v>
@@ -812,8 +812,8 @@ false</pre>
<p>The returned value is <c>true</c> unless <c>info</c> is part
of <c>OptionList</c>.
</p>
- <p><c>erlang:demonitor(MonitorRef, [])</c> is equivalent to
- <seealso marker="#demonitor/1">erlang:demonitor(MonitorRef)</seealso>.</p>
+ <p><c>demonitor(MonitorRef, [])</c> is equivalent to
+ <seealso marker="#demonitor/1">demonitor(MonitorRef)</seealso>.</p>
<p>Currently the following <c>Option</c>s are valid:</p>
<taglist>
<tag><c>flush</c></tag>
@@ -821,11 +821,11 @@ false</pre>
<p>Remove (one) <c>{_, MonitorRef, _, _, _}</c> message,
if there is one, from the callers message queue after
monitoring has been stopped.</p>
- <p>Calling <c>erlang:demonitor(MonitorRef, [flush])</c>
+ <p>Calling <c>demonitor(MonitorRef, [flush])</c>
is equivalent to the following, but more efficient:</p>
<code type="none">
- erlang:demonitor(MonitorRef),
+ demonitor(MonitorRef),
receive
{_, MonitorRef, _, _, _} ->
true
@@ -863,7 +863,7 @@ false</pre>
</note>
<p>Failure: <c>badarg</c> if <c>OptionList</c> is not a list, or
if <c>Option</c> is not a valid option, or the same failure as for
- <seealso marker="#demonitor/1">erlang:demonitor/1</seealso></p>
+ <seealso marker="#demonitor/1">demonitor/1</seealso></p>
</desc>
</func>
<func>
@@ -944,7 +944,7 @@ b</pre>
</desc>
</func>
<func>
- <name>erlang:error(Reason)</name>
+ <name>error(Reason)</name>
<fsummary>Stop execution with a given reason</fsummary>
<type>
<v>Reason = term()</v>
@@ -957,7 +957,7 @@ b</pre>
function first). Since evaluating this function causes
the process to terminate, it has no return value.</p>
<pre>
-> <input>catch erlang:error(foobar).</input>
+> <input>catch error(foobar).</input>
{'EXIT',{foobar,[{erl_eval,do_apply,5},
{erl_eval,expr,5},
{shell,exprs,6},
@@ -966,7 +966,7 @@ b</pre>
</desc>
</func>
<func>
- <name>erlang:error(Reason, Args)</name>
+ <name>error(Reason, Args)</name>
<fsummary>Stop execution with a given reason</fsummary>
<type>
<v>Reason = term()</v>
@@ -1483,7 +1483,7 @@ os_prompt%</pre>
</desc>
</func>
<func>
- <name>erlang:integer_to_list(Integer, Base) -> string()</name>
+ <name>integer_to_list(Integer, Base) -> string()</name>
<fsummary>Text representation of an integer</fsummary>
<type>
<v>Integer = int()</v>
@@ -1493,7 +1493,7 @@ os_prompt%</pre>
<p>Returns a string which corresponds to the text
representation of <c>Integer</c> in base <c>Base</c>.</p>
<pre>
-> <input>erlang:integer_to_list(1023, 16).</input>
+> <input>integer_to_list(1023, 16).</input>
"3FF"</pre>
</desc>
</func>
@@ -1932,7 +1932,7 @@ os_prompt%</pre>
</desc>
</func>
<func>
- <name>erlang:list_to_integer(String, Base) -> int()</name>
+ <name>list_to_integer(String, Base) -> int()</name>
<fsummary>Convert from text representation to an integer</fsummary>
<type>
<v>String = string()</v>
@@ -1942,7 +1942,7 @@ os_prompt%</pre>
<p>Returns an integer whose text representation in base
<c>Base</c> is <c>String</c>.</p>
<pre>
-> <input>erlang:list_to_integer("3FF", 16).</input>
+> <input>list_to_integer("3FF", 16).</input>
1023</pre>
<p>Failure: <c>badarg</c> if <c>String</c> contains a bad
representation of an integer.</p>
@@ -2488,7 +2488,7 @@ os_prompt%</pre>
</desc>
</func>
<func>
- <name>erlang:monitor(Type, Item) -> MonitorRef</name>
+ <name>monitor(Type, Item) -> MonitorRef</name>
<fsummary>Start monitoring</fsummary>
<type>
<v>Type = process</v>
@@ -2524,7 +2524,7 @@ os_prompt%</pre>
<note>
<p>When a process is monitored by registered name, the process
that has the registered name at the time when
- <c>erlang:monitor/2</c> is called will be monitored.
+ <c>monitor/2</c> is called will be monitored.
The monitor will not be effected, if the registered name is
unregistered.</p>
</note>
@@ -2558,20 +2558,20 @@ os_prompt%</pre>
</item>
</taglist>
<note>
- <p>If/when <c>erlang:monitor/2</c> is extended (e.g. to
+ <p>If/when <c>monitor/2</c> is extended (e.g. to
handle other item types than <c>process</c>), other
possible values for <c>Object</c>, and <c>Info</c> in the
<c>'DOWN'</c> message will be introduced.</p>
</note>
<p>The monitoring is turned off either when the <c>'DOWN'</c>
message is sent, or when
- <seealso marker="#demonitor/1">erlang:demonitor/1</seealso>
+ <seealso marker="#demonitor/1">demonitor/1</seealso>
is called.</p>
<p>If an attempt is made to monitor a process on an older node
(where remote process monitoring is not implemented or one
where remote process monitoring by registered name is not
implemented), the call fails with <c>badarg</c>.</p>
- <p>Making several calls to <c>erlang:monitor/2</c> for the same
+ <p>Making several calls to <c>monitor/2</c> for the same
<c>Item</c> is not an error; it results in as many, completely
independent, monitorings.</p>
<note>
@@ -3899,11 +3899,11 @@ os_prompt%</pre>
<tag><c>{monitored_by, Pids}</c></tag>
<item>
<p>A list of pids that are monitoring the process (with
- <c>erlang:monitor/2</c>).</p>
+ <c>monitor/2</c>).</p>
</item>
<tag><c>{monitors, Monitors}</c></tag>
<item>
- <p>A list of monitors (started by <c>erlang:monitor/2</c>)
+ <p>A list of monitors (started by <c>monitor/2</c>)
that are active for the process. For a local process
monitor or a remote process monitor by pid, the list item
is <c>{process, Pid}</c>, and for a remote process
@@ -4092,7 +4092,7 @@ os_prompt%</pre>
terminate, it has no return value - unless the arguments are
invalid, in which case the function <em>returns the error reason</em>, that is <c>badarg</c>. If you want to be
really sure not to return you can call
- <c>erlang:error(erlang:raise(Class, Reason, Stacktrace))</c>
+ <c>error(erlang:raise(Class, Reason, Stacktrace))</c>
and hope to distinguish exceptions later.</p>
</desc>
</func>
@@ -4693,7 +4693,7 @@ true</pre>
<tag><c>monitor</c></tag>
<item>
<p>Monitor the new process (just like
- <seealso marker="#monitor/2">erlang:monitor/2</seealso> does).</p>
+ <seealso marker="#monitor/2">monitor/2</seealso> does).</p>
</item>
<tag><c>{priority, Level}</c></tag>
<item>
diff --git a/erts/emulator/beam/erl_bif_binary.c b/erts/emulator/beam/erl_bif_binary.c
index 024ff2a684..b6a445c55c 100644
--- a/erts/emulator/beam/erl_bif_binary.c
+++ b/erts/emulator/beam/erl_bif_binary.c
@@ -555,8 +555,12 @@ static void ac_init_find_all(ACFindAllState *state, ACTrie *act, Sint startpos,
static void ac_restore_find_all(ACFindAllState *state, char *buff)
{
memcpy(state,buff,sizeof(ACFindAllState));
- state->out = erts_alloc(ERTS_ALC_T_TMP, sizeof(FindallData) * (state->allocated));
- memcpy(state->out,buff+sizeof(ACFindAllState),sizeof(FindallData)*state->m);
+ if (state->allocated > 0) {
+ state->out = erts_alloc(ERTS_ALC_T_TMP, sizeof(FindallData) * (state->allocated));
+ memcpy(state->out,buff+sizeof(ACFindAllState),sizeof(FindallData)*state->m);
+ } else {
+ state->out = NULL;
+ }
}
static void ac_serialize_find_all(ACFindAllState *state, char *buff)
@@ -828,10 +832,14 @@ static void bm_init_find_all(BMFindAllState *state, Sint startpos, Uint len)
static void bm_restore_find_all(BMFindAllState *state, char *buff)
{
memcpy(state,buff,sizeof(BMFindAllState));
- state->out = erts_alloc(ERTS_ALC_T_TMP, sizeof(FindallData) *
- (state->allocated));
- memcpy(state->out,buff+sizeof(BMFindAllState),
- sizeof(FindallData)*state->m);
+ if (state->allocated > 0) {
+ state->out = erts_alloc(ERTS_ALC_T_TMP, sizeof(FindallData) *
+ (state->allocated));
+ memcpy(state->out,buff+sizeof(BMFindAllState),
+ sizeof(FindallData)*state->m);
+ } else {
+ state->out = NULL;
+ }
}
static void bm_serialize_find_all(BMFindAllState *state, char *buff)
@@ -1128,7 +1136,7 @@ static int do_binary_match(Process *p, Eterm subject, Uint hsstart, Uint hsend,
ret = am_nomatch;
} else if (acr == AC_RESTART) {
int x = (sizeof(state) / sizeof(Eterm)) +
- !!(sizeof(BMFindFirstState) % sizeof(Eterm));
+ !!(sizeof(ACFindFirstState) % sizeof(Eterm));
#ifdef HARDDEBUG
erts_printf("Trap ac!\n");
#endif
diff --git a/erts/emulator/drivers/common/inet_drv.c b/erts/emulator/drivers/common/inet_drv.c
index 3f761eeb19..3de48194fb 100644
--- a/erts/emulator/drivers/common/inet_drv.c
+++ b/erts/emulator/drivers/common/inet_drv.c
@@ -2174,7 +2174,7 @@ static int http_error_inetdrv(void* arg, const char* buf, int len)
ErlDrvTermData spec[19];
if (desc->inet.active == INET_PASSIVE) {
- /* {inet_async,S,Ref,{error,{http_error,Line}}} */
+ /* {inet_async,S,Ref,{ok,{http_error,Line}}} */
int req;
int aid;
ErlDrvTermData caller;
@@ -2184,7 +2184,7 @@ static int http_error_inetdrv(void* arg, const char* buf, int len)
i = LOAD_ATOM(spec, i, am_inet_async);
i = LOAD_PORT(spec, i, desc->inet.dport);
i = LOAD_INT(spec, i, aid);
- i = LOAD_ATOM(spec, i, am_error);
+ i = LOAD_ATOM(spec, i, am_ok);
i = LOAD_ATOM(spec, i, am_http_error);
i = http_load_string(desc, spec, i, buf, len);
i = LOAD_TUPLE(spec, i, 2);
diff --git a/erts/emulator/test/port_SUITE.erl b/erts/emulator/test/port_SUITE.erl
index 77fa75b78f..a7476ca9bb 100644
--- a/erts/emulator/test/port_SUITE.erl
+++ b/erts/emulator/test/port_SUITE.erl
@@ -2305,7 +2305,11 @@ load_driver(Dir, Driver) ->
close_deaf_port(doc) -> ["Send data to port program that does not read it, then close port."];
close_deaf_port(suite) -> [];
close_deaf_port(Config) when is_list(Config) ->
- Port = open_port({spawn,"sleep 999999"},[]),
- erlang:port_command(Port,"Hello, can you hear me!?!?"),
- port_close(Port),
+ ?line Dog = test_server:timetrap(test_server:seconds(100)),
+ ?line DataDir = ?config(data_dir, Config),
+ ?line DeadPort = os:find_executable("dead_port", DataDir),
+
+ ?line Port = open_port({spawn,DeadPort++" 60"},[]),
+ ?line erlang:port_command(Port,"Hello, can you hear me!?!?"),
+ ?line port_close(Port),
ok.
diff --git a/erts/emulator/test/port_SUITE_data/Makefile.src b/erts/emulator/test/port_SUITE_data/Makefile.src
index d97b37c9ae..ff822ae720 100644
--- a/erts/emulator/test/port_SUITE_data/Makefile.src
+++ b/erts/emulator/test/port_SUITE_data/Makefile.src
@@ -3,7 +3,7 @@ LD = @LD@
CFLAGS = @CFLAGS@ -I@erl_include@ @DEFS@
CROSSLDFLAGS = @CROSSLDFLAGS@
-PROGS = port_test@exe@ echo_args@exe@
+PROGS = port_test@exe@ echo_args@exe@ dead_port@exe@
DRIVERS = echo_drv@dll@ exit_drv@dll@ failure_drv@dll@
all: $(PROGS) $(DRIVERS) port_test.@EMULATOR@
diff --git a/erts/emulator/test/port_SUITE_data/dead_port.c b/erts/emulator/test/port_SUITE_data/dead_port.c
new file mode 100644
index 0000000000..6fa77112be
--- /dev/null
+++ b/erts/emulator/test/port_SUITE_data/dead_port.c
@@ -0,0 +1,102 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2001-2010. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Erlang Public License,
+ * Version 1.1, (the "License"); you may not use this file except in
+ * compliance with the License. You should have received a copy of the
+ * Erlang Public License along with this software. If not, it can be
+ * retrieved online at http://www.erlang.org/.
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * %CopyrightEnd%
+ */
+
+#ifdef VXWORKS
+#include <vxWorks.h>
+#include <taskVarLib.h>
+#include <taskLib.h>
+#include <sysLib.h>
+#include <string.h>
+#include <ioLib.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#ifndef __WIN32__
+#include <unistd.h>
+
+#ifdef VXWORKS
+#include "reclaim.h"
+#include <sys/times.h>
+#else
+#include <sys/time.h>
+#endif
+
+#define O_BINARY 0
+#define _setmode(fd, mode)
+#endif
+
+#ifdef __WIN32__
+#include "windows.h"
+#include "winbase.h"
+#endif
+
+
+#ifdef VXWORKS
+#define MAIN(argc, argv) port_test(argc, argv)
+#else
+#define MAIN(argc, argv) main(argc, argv)
+#endif
+
+
+extern int errno;
+
+static void delay(unsigned ms);
+
+
+MAIN(argc, argv)
+int argc;
+char *argv[];
+{
+ int x;
+ if (argc < 2) {
+ fprintf(stderr,"Usage %s <seconds>\n",argv[0]);
+ return 1;
+ }
+ if ((x = atoi(argv[1])) <= 0) {
+ fprintf(stderr,"Usage %s <seconds>\n",argv[0]);
+ return 1;
+ }
+ delay(x*1000);
+ return 0;
+}
+
+static void
+delay(unsigned ms)
+{
+#ifdef VXWORKS
+ taskDelay((sysClkRateGet() * ms) / 1000);
+#else
+#ifdef __WIN32__
+ Sleep(ms);
+#else
+ struct timeval t;
+ t.tv_sec = ms/1000;
+ t.tv_usec = (ms % 1000) * 1000;
+
+ select(0, NULL, NULL, NULL, &t);
+#endif
+#endif
+}
diff --git a/erts/preloaded/ebin/erl_prim_loader.beam b/erts/preloaded/ebin/erl_prim_loader.beam
index 7b824f1ab4..222809e662 100644
--- a/erts/preloaded/ebin/erl_prim_loader.beam
+++ b/erts/preloaded/ebin/erl_prim_loader.beam
Binary files differ
diff --git a/erts/preloaded/ebin/erlang.beam b/erts/preloaded/ebin/erlang.beam
index 3cab91b722..65c7369b76 100644
--- a/erts/preloaded/ebin/erlang.beam
+++ b/erts/preloaded/ebin/erlang.beam
Binary files differ
diff --git a/erts/preloaded/ebin/init.beam b/erts/preloaded/ebin/init.beam
index 9f88ddd51e..f1b54b7fcb 100644
--- a/erts/preloaded/ebin/init.beam
+++ b/erts/preloaded/ebin/init.beam
Binary files differ
diff --git a/erts/preloaded/ebin/otp_ring0.beam b/erts/preloaded/ebin/otp_ring0.beam
index 4c9cc9675b..abf17bcb0e 100644
--- a/erts/preloaded/ebin/otp_ring0.beam
+++ b/erts/preloaded/ebin/otp_ring0.beam
Binary files differ
diff --git a/erts/preloaded/ebin/prim_file.beam b/erts/preloaded/ebin/prim_file.beam
index 9a4904b6a1..a3f300268f 100644
--- a/erts/preloaded/ebin/prim_file.beam
+++ b/erts/preloaded/ebin/prim_file.beam
Binary files differ
diff --git a/erts/preloaded/ebin/prim_inet.beam b/erts/preloaded/ebin/prim_inet.beam
index 71f6643368..a777971b32 100644
--- a/erts/preloaded/ebin/prim_inet.beam
+++ b/erts/preloaded/ebin/prim_inet.beam
Binary files differ
diff --git a/erts/preloaded/ebin/prim_zip.beam b/erts/preloaded/ebin/prim_zip.beam
index c57d37725e..0fe38a1fb2 100644
--- a/erts/preloaded/ebin/prim_zip.beam
+++ b/erts/preloaded/ebin/prim_zip.beam
Binary files differ
diff --git a/erts/preloaded/ebin/zlib.beam b/erts/preloaded/ebin/zlib.beam
index 6b14d3fd66..7108bf44d0 100644
--- a/erts/preloaded/ebin/zlib.beam
+++ b/erts/preloaded/ebin/zlib.beam
Binary files differ
diff --git a/erts/test/Makefile b/erts/test/Makefile
index 796403e182..94458da019 100644
--- a/erts/test/Makefile
+++ b/erts/test/Makefile
@@ -28,6 +28,7 @@ EBIN = .
# ----------------------------------------------------
MODULES= \
+ autoimport_SUITE \
erlc_SUITE \
install_SUITE \
nt_SUITE \
@@ -38,12 +39,14 @@ MODULES= \
erlexec_SUITE \
z_SUITE
+ERL_XML = $(ERL_TOP)/erts/doc/src/erlang.xml
+ERL_XML_TARGET = autoimport_SUITE_data/erlang.xml
ERL_FILES= $(MODULES:%=%.erl)
TARGET_FILES = $(MODULES:%=$(EBIN)/%.$(EMULATOR))
-EXTRA_FILES = install_SUITE_data/install_bin
+EXTRA_FILES = install_SUITE_data/install_bin $(ERL_XML_TARGET)
# ----------------------------------------------------
# Release directory specification
@@ -65,6 +68,10 @@ install_SUITE_data/install_bin: ../../make/install_bin
rm -f $@
cp -p $< $@
+$(ERL_XML_TARGET): $(ERL_XML)
+ rm -f $@
+ cp -p $< $@
+
clean:
rm -f $(TARGET_FILES) $(EXTRA_FILES)
rm -f core *~
diff --git a/erts/test/autoimport_SUITE.erl b/erts/test/autoimport_SUITE.erl
new file mode 100644
index 0000000000..2430dac78d
--- /dev/null
+++ b/erts/test/autoimport_SUITE.erl
@@ -0,0 +1,163 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%% Purpose: Test erlang.xml re autoimports
+-module(autoimport_SUITE).
+
+-include_lib("test_server/include/test_server.hrl").
+-export([all/1,init_per_testcase/2,fin_per_testcase/2,autoimports/1]).
+-define(TEST_TIMEOUT, ?t:seconds(180)).
+
+all(suite) -> [autoimports].
+
+init_per_testcase(_Func, Config) ->
+ Dog = test_server:timetrap(?TEST_TIMEOUT),
+ [{watchdog, Dog} | Config].
+
+fin_per_testcase(_Func, Config) ->
+ Dog = ?config(watchdog, Config),
+ catch test_server:timetrap_cancel(Dog),
+ ok.
+
+
+autoimports(suite) ->
+ [];
+autoimports(doc) ->
+ ["Check that erlang.xml documents autoimports correctly"];
+autoimports(Config) when is_list(Config) ->
+ ?line XML = filename:join([?config(data_dir,Config),"erlang.xml"]),
+ ?line case xml(XML) of
+ [] ->
+ ok;
+ List ->
+ lists:foreach(fun({[],F,A}) ->
+ io:format("erlang:~s/~p is wrongly "
+ "documented as ~s/~p~n",
+ [F,A,F,A]);
+ ({"erlang",F,A}) ->
+ io:format("~s/~p is wrongly "
+ "documented as "
+ "erlang:~s/~p~n",
+ [F,A,F,A])
+ end,List),
+ ?t:fail({wrong_autoimports,List})
+ end.
+
+%%
+%% Ugly chunk of code to heuristically analyze the erlang.xml
+%% documentation file. Don't view this as an example...
+%%
+
+xml(XMLFile) ->
+ {ok,File} = file:open(XMLFile,[read]),
+ DocData = xloop(file:read_line(File),File),
+ file:close(File),
+ analyze(DocData).
+
+xloop({ok,Line},File) ->
+ case re:run(Line,"\\<name\\>",[{capture,none}]) of
+ nomatch ->
+ xloop(file:read_line(File),File);
+ match ->
+ X = re:replace(Line,"\\).*",")",[{return,list}]),
+ Y = re:replace(X,".*\\>","",[{return,list}]),
+ Mod = get_module(Y),
+ Rest1 = fstrip(Mod++":",Y),
+ Func = get_function(Rest1),
+ Rest2 = fstrip(Func++"(", Rest1),
+ Argc = count_args(Rest2,1,0,false),
+ [{Mod,Func,Argc} |
+ xloop(file:read_line(File),File)]
+ end;
+xloop(_,_) ->
+ [].
+
+analyze([{[],Func,Arity}|T]) ->
+ case erl_internal:bif(list_to_atom(Func),Arity) of
+ true ->
+ analyze(T);
+ false ->
+ [{[],Func,Arity} |
+ analyze(T)]
+ end;
+analyze([{"erlang",Func,Arity}|T]) ->
+ case erl_internal:bif(list_to_atom(Func),Arity) of
+ true ->
+ [{"erlang",Func,Arity}|analyze(T)];
+ false ->
+ analyze(T)
+ end;
+analyze([_|T]) ->
+ analyze(T);
+analyze([]) ->
+ [].
+
+
+count_args([],_,N,false) ->
+ N;
+count_args([],_,N,true) ->
+ N+1;
+count_args(_,0,N,true) ->
+ N+1;
+count_args(_,0,N,false) ->
+ N;
+count_args([Par|T],Level,N,Got) when (Par =:= 40) or
+ (Par =:= 123) or (Par =:= 91) ->
+ count_args(T,Level+1,N,(Level =:= 1) or Got);
+count_args([41|T],1,N,true) ->
+ count_args(T,0,N+1,false);
+count_args([Par|T],Level,N, Got) when (Par =:= 41) or
+ (Par =:= 125) or (Par =:= 93) ->
+ count_args(T,Level-1,N,Got);
+count_args([$,|T],1,N,true) ->
+ count_args(T,1,N+1,false);
+count_args([$ |T],A,B,C) ->
+ count_args(T,A,B,C);
+count_args([_|T],1,N,_) ->
+ count_args(T,1,N,true);
+count_args([_|T],A,B,C) ->
+ count_args(T,A,B,C).
+
+fstrip([],X) ->
+ X;
+fstrip(_,[]) ->
+ [];
+fstrip([H|T1],[H|T2]) ->
+ fstrip(T1,T2);
+fstrip(_,L) ->
+ L.
+
+get_module(X) ->
+ get_module(X,[]).
+get_module([],_) ->
+ [];
+get_module([$:|_],Acc) ->
+ lists:reverse(Acc);
+get_module([40|_],_) -> %(
+ [];
+get_module([H|T],Acc) ->
+ get_module(T,[H|Acc]).
+
+get_function(X) ->
+ get_function(X,[]).
+get_function([],_) ->
+ [];
+get_function([40|_],Acc) -> %(
+ lists:reverse(Acc);
+get_function([H|T],Acc) ->
+ get_function(T,[H|Acc]).
diff --git a/erts/test/autoimport_SUITE_data/dummy.txt b/erts/test/autoimport_SUITE_data/dummy.txt
new file mode 100644
index 0000000000..972643e527
--- /dev/null
+++ b/erts/test/autoimport_SUITE_data/dummy.txt
@@ -0,0 +1,19 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%% Purpouse: Dummy