aboutsummaryrefslogtreecommitdiffstats
path: root/erts
diff options
context:
space:
mode:
Diffstat (limited to 'erts')
-rw-r--r--erts/aclocal.m47
-rw-r--r--erts/configure.in19
-rw-r--r--erts/doc/src/alt_dist.xml2
-rw-r--r--erts/doc/src/erl_nif.xml6
-rw-r--r--erts/doc/src/erlang.xml66
-rw-r--r--erts/doc/src/erlsrv.xml17
-rw-r--r--erts/doc/src/notes.xml2
-rw-r--r--erts/doc/src/start_erl.xml29
-rw-r--r--erts/doc/src/zlib.xml60
-rw-r--r--erts/emulator/Makefile.in10
-rw-r--r--erts/emulator/beam/beam_bif_load.c30
-rw-r--r--erts/emulator/beam/bif.tab8
-rw-r--r--erts/emulator/beam/erl_bif_trace.c2
-rw-r--r--erts/emulator/beam/erl_db.c10
-rw-r--r--erts/emulator/beam/erl_gc.c40
-rw-r--r--erts/emulator/beam/erl_init.c4
-rw-r--r--erts/emulator/beam/erl_nif.c10
-rw-r--r--erts/emulator/beam/erl_process.c7
-rw-r--r--erts/emulator/beam/erl_threads.h15
-rw-r--r--erts/emulator/beam/external.c49
-rw-r--r--erts/emulator/beam/external.h1
-rw-r--r--erts/emulator/drivers/common/inet_drv.c2
-rwxr-xr-xerts/emulator/drivers/win32/win_efile.c6
-rw-r--r--erts/emulator/sys/common/erl_poll.c2
-rw-r--r--erts/emulator/sys/unix/sys.c4
-rw-r--r--erts/emulator/sys/win32/sys.c5
-rw-r--r--erts/emulator/test/binary_SUITE.erl16
-rw-r--r--erts/emulator/test/code_SUITE.erl32
-rw-r--r--erts/emulator/test/distribution_SUITE.erl2
-rw-r--r--erts/emulator/test/driver_SUITE.erl2
-rw-r--r--erts/emulator/test/mtx_SUITE_data/mtx_SUITE.c46
-rw-r--r--erts/emulator/test/nif_SUITE.erl6
-rw-r--r--erts/emulator/test/nif_SUITE_data/nif_SUITE.c38
-rw-r--r--erts/epmd/src/epmd.c6
-rw-r--r--erts/epmd/src/epmd_cli.c5
-rw-r--r--erts/epmd/src/epmd_srv.c3
-rw-r--r--erts/etc/win32/erlsrv/erlsrv_interactive.c189
-rw-r--r--erts/etc/win32/erlsrv/erlsrv_interactive.h2
-rw-r--r--erts/etc/win32/start_erl.c159
-rw-r--r--erts/example/matrix_nif.c85
-rw-r--r--erts/include/internal/ethread_header_config.h.in2
-rw-r--r--erts/lib_src/common/erl_misc_utils.c6
-rw-r--r--erts/lib_src/common/erl_printf.c12
-rw-r--r--erts/preloaded/ebin/zlib.beambin12148 -> 11876 bytes
-rw-r--r--erts/preloaded/src/erl_prim_loader.erl4
-rw-r--r--erts/preloaded/src/init.erl2
-rw-r--r--erts/preloaded/src/prim_file.erl6
-rw-r--r--erts/preloaded/src/prim_zip.erl2
-rw-r--r--erts/preloaded/src/zlib.erl115
-rw-r--r--erts/test/autoimport_SUITE.erl11
-rw-r--r--erts/test/erlc_SUITE.erl27
51 files changed, 804 insertions, 387 deletions
diff --git a/erts/aclocal.m4 b/erts/aclocal.m4
index b64380e817..7d9d099bba 100644
--- a/erts/aclocal.m4
+++ b/erts/aclocal.m4
@@ -125,6 +125,9 @@ AC_DEFUN(LM_FIND_EMU_CC,
ac_cv_prog_emu_cc,
[
AC_TRY_COMPILE([],[
+#ifdef __llvm__
+#error "llvm is currently unable to compile beam_emu.c"
+#endif
__label__ lbl1;
__label__ lbl2;
int x = magic();
@@ -140,7 +143,7 @@ lbl2:
],ac_cv_prog_emu_cc=$CC,ac_cv_prog_emu_cc=no)
if test $ac_cv_prog_emu_cc = no; then
- for ac_progname in emu_cc.sh gcc; do
+ for ac_progname in emu_cc.sh gcc-4.2 gcc; do
IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
ac_dummy="$PATH"
for ac_dir in $ac_dummy; do
@@ -1298,7 +1301,7 @@ int main(void)
esac
test $enable_ethread_pre_pentium4_compatibility = yes &&
- AC_DEFINE(ETHR_PRE_PENTIUM4_COMPAT, 1, [Define if you want compatibilty with x86 processors before pentium4.])
+ AC_DEFINE(ETHR_PRE_PENTIUM4_COMPAT, 1, [Define if you want compatibility with x86 processors before pentium4.])
AC_DEFINE(ETHR_HAVE_ETHREAD_DEFINES, 1, \
[Define if you have all ethread defines])
diff --git a/erts/configure.in b/erts/configure.in
index fac07f8b6a..03e27c9dad 100644
--- a/erts/configure.in
+++ b/erts/configure.in
@@ -1673,6 +1673,15 @@ esac
AC_C_BIGENDIAN
+dnl fdatasync syscall (Unix only)
+AC_CHECK_FUNCS([fdatasync])
+
+dnl Find which C libraries are required to use fdatasync
+dnl TODO: Remove check once SunOS >= 5.11 is required by erts.
+dnl fdatasync requires linking against -lrt on SunOS <= 5.10.
+dnl OpenSolaris 2009.06 is SunOS 5.11 and does not require -lrt.
+AC_SEARCH_LIBS(fdatasync, [rt])
+
dnl ----------------------------------------------------------------------
dnl Checks for library functions.
dnl ----------------------------------------------------------------------
@@ -1860,12 +1869,6 @@ fi
dnl Need by run_erl.
AC_CHECK_FUNCS([openpty])
-dnl fdatasync syscall (Unix only)
-AC_CHECK_FUNCS([fdatasync])
-
-dnl Find which C libraries are required to use fdatasync
-AC_SEARCH_LIBS(fdatasync, [rt])
-
AC_CHECK_HEADERS(net/if_dl.h ifaddrs.h netpacket/packet.h)
AC_CHECK_FUNCS([getifaddrs])
@@ -3722,7 +3725,7 @@ case "$erl_xcomp_without_sysroot-$with_ssl" in
SSL_RUNTIME_LIBDIR="$rdir/lib"
SSL_LIBDIR="$dir/lib"
SSL_CRYPTO_LIBNAME=libeay32
- SSL_CRYPTO_LIBNAME=ssleay32
+ SSL_SSL_LIBNAME=ssleay32
elif test -f "$dir/lib/openssl.lib"; then
SSL_RUNTIME_LIBDIR="$rdir/lib"
SSL_LIBDIR="$dir/lib"
@@ -3904,7 +3907,7 @@ dnl so it is - be adoptable
elif test -f "$with_ssl/lib/libeay32.lib"; then
SSL_LIBDIR="$with_ssl/lib"
SSL_CRYPTO_LIBNAME=libeay32
- SSL_CRYPTO_LIBNAME=ssleay32
+ SSL_SSL_LIBNAME=ssleay32
else
# This probably wont work, but that's what the user said, so...
SSL_LIBDIR="$with_ssl/lib"
diff --git a/erts/doc/src/alt_dist.xml b/erts/doc/src/alt_dist.xml
index 36d83a685b..c30e04fce7 100644
--- a/erts/doc/src/alt_dist.xml
+++ b/erts/doc/src/alt_dist.xml
@@ -377,7 +377,7 @@
( 1) typedef enum {
( 2) portTypeUnknown, /* An uninitialized port */
( 3) portTypeListener, /* A listening port/socket */
-( 4) portTypeAcceptor, /* An intermidiate stage when accepting
+( 4) portTypeAcceptor, /* An intermediate stage when accepting
( 5) on a listen port */
( 6) portTypeConnector, /* An intermediate stage when connecting */
( 7) portTypeCommand, /* A connected open port in command mode */
diff --git a/erts/doc/src/erl_nif.xml b/erts/doc/src/erl_nif.xml
index cdce4ec0b8..48839e9081 100644
--- a/erts/doc/src/erl_nif.xml
+++ b/erts/doc/src/erl_nif.xml
@@ -216,14 +216,14 @@ ok
<p/>
<code type="none">
ERL_NIF_TERM term;
- MyStruct* ptr = enif_alloc_resource(my_resource_type, sizeof(MyStruct));
+ MyStruct* obj = enif_alloc_resource(my_resource_type, sizeof(MyStruct));
/* initialize struct ... */
- term = enif_make_resource(env, ptr);
+ term = enif_make_resource(env, obj);
if (keep_a_reference_of_our_own) {
- /* store 'ptr' in static variable, private data or other resource object */
+ /* store 'obj' in static variable, private data or other resource object */
}
else {
enif_release_resource(obj);
diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml
index 7cfab0785d..2fabc6d62d 100644
--- a/erts/doc/src/erlang.xml
+++ b/erts/doc/src/erlang.xml
@@ -518,6 +518,18 @@
</func>
<func>
+ <name>check_old_code(Module) -> boolean()</name>
+ <fsummary>Check if a module has old code</fsummary>
+ <type>
+ <v>Module = atom()</v>
+ </type>
+ <desc>
+ <p>Returns <c>true</c> if the <c>Module</c> has old code,
+ and <c>false</c> otherwise.</p>
+ <p>See also <seealso marker="kernel:code">code(3)</seealso>.</p>
+ </desc>
+ </func>
+ <func>
<name>check_process_code(Pid, Module) -> boolean()</name>
<fsummary>Check if a process is executing old code for a module</fsummary>
<type>
@@ -1023,6 +1035,56 @@ b</pre>
</desc>
</func>
<func>
+ <name>erlang:external_size(Term) -> integer() >= 0</name>
+ <fsummary>Calculate the maximum size for a term encoded in the Erlang
+ external term format</fsummary>
+ <type>
+ <v>Term = term()</v>
+ </type>
+ <desc>
+ <p>Calculates, without doing the encoding, the maximum byte size for
+ a term encoded in the Erlang external term format. The following
+ condition applies always:</p>
+ <p>
+ <pre>
+> <input>Size1 = byte_size(term_to_binary(Term)),</input>
+> <input>Size2 = erlang:external_size(Term),</input>
+> <input>true = Size1 =&lt; Size2.</input>
+true
+ </pre>
+ </p>
+ <p>This is equivalent to a call to: <code>erlang:external_size(Term, [])
+ </code></p>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:external_size(Term, [Option]) -> integer() >= 0</name>
+ <fsummary>Calculate the maximum size for a term encoded in the Erlang
+ external term format</fsummary>
+ <type>
+ <v>Term = term()</v>
+ <v>Option = {minor_version, Version}</v>
+ </type>
+ <desc>
+ <p>Calculates, without doing the encoding, the maximum byte size for
+ a term encoded in the Erlang external term format. The following
+ condition applies always:</p>
+ <p>
+ <pre>
+> <input>Size1 = byte_size(term_to_binary(Term, Options)),</input>
+> <input>Size2 = erlang:external_size(Term, Options),</input>
+> <input>true = Size1 =&lt; Size2.</input>
+true
+ </pre>
+ </p>
+ <p>The option <c>{minor_version, Version}</c> specifies how floats
+ are encoded. See
+ <seealso marker="#term_to_binary/2">term_to_binary/2</seealso> for
+ a more detailed description.
+ </p>
+ </desc>
+ </func>
+ <func>
<name>float(Number) -> float()</name>
<fsummary>Convert a number to a float</fsummary>
<type>
@@ -5888,7 +5950,7 @@ true</pre>
</item>
<tag><c>wordsize</c></tag>
<item>
- <p>Same as <c>{wordsize, internal}</c></p>
+ <p>Same as <c>{wordsize, internal}.</c></p>
</item>
<tag><c>{wordsize, internal}</c></tag>
<item>
@@ -5897,7 +5959,7 @@ true</pre>
and on a pure 64-bit architecture 8 is returned. On a
halfword 64-bit emulator, 4 is returned, as the Erlang
terms are stored using a virtual wordsize of half the
- systems wordsize.</p>
+ system's wordsize.</p>
</item>
<tag><c>{wordsize, external}</c></tag>
<item>
diff --git a/erts/doc/src/erlsrv.xml b/erts/doc/src/erlsrv.xml
index 0dfad2a112..919caa9542 100644
--- a/erts/doc/src/erlsrv.xml
+++ b/erts/doc/src/erlsrv.xml
@@ -273,7 +273,7 @@
</desc>
</func>
<func>
- <name>erlsrv {start | stop | disable | enable} &lt;service-name></name>
+ <name>erlsrv {start | start_disabled | stop | disable | enable} &lt;service-name></name>
<fsummary>Manipulate the current service status.</fsummary>
<desc>
<p>These commands are only added for convenience, the normal
@@ -287,6 +287,21 @@
service actually is stopped. Enabling a service sets it in
automatic mode, that is started at boot. This command cannot
set the service to manual. </p>
+
+ <p>The <c>start_disabled</c> command operates on a service
+ regardless of if it's enabled/disabled or started/stopped. It
+ does this by first enabling it (regardless of if it's enabled
+ or not), then starting it (if it's not already started) and
+ then disabling it. The result will be a disabled but started
+ service, regardless of its earlier state. This is useful for
+ starting services temporarily during a release upgrade. The
+ difference between using <c>start_disabled</c> and the
+ sequence <c>enable</c>, <c>start</c> and <c>disable</c> is
+ that all other <c>erlsrv</c> commands are locked out during
+ the sequence of operations in <c>start_disable</c>, making the
+ operation atomic from an <c>erlsrv</c> user's point of
+ view.</p>
+
</desc>
</func>
<func>
diff --git a/erts/doc/src/notes.xml b/erts/doc/src/notes.xml
index 3733fb2db9..3e9e6a35f2 100644
--- a/erts/doc/src/notes.xml
+++ b/erts/doc/src/notes.xml
@@ -4534,7 +4534,7 @@
The race occurred when a process removed a table during
termination simultaneously as another process removed the
same table via <c>ets:delete/1</c> and a third process
- created a table that accidentaly got the same internal
+ created a table that accidentally got the same internal
table index as the table being removed.</p>
<p>
Own Id: OTP-7349</p>
diff --git a/erts/doc/src/start_erl.xml b/erts/doc/src/start_erl.xml
index 21cc901f52..6f6930af7e 100644
--- a/erts/doc/src/start_erl.xml
+++ b/erts/doc/src/start_erl.xml
@@ -69,12 +69,29 @@
<c><![CDATA[erl]]></c> program. Everything <em>after</em><c><![CDATA[++]]></c> is
interpreted as options to <c><![CDATA[start_erl]]></c> itself.</item>
<tag>-reldir &lt;release root&gt;</tag>
- <item>Mandatory if the environment variable <c><![CDATA[RELDIR]]></c> is not
- specified. Tells start_erl where the root of the
- release tree is placed in the file-system
- (like &lt;Erlang root&gt;\\releases). The
- <c><![CDATA[start_erl.data]]></c> file is expected to be placed in
- this directory (if not otherwise specified).</item>
+
+ <item>Mandatory if the environment variable
+ <c><![CDATA[RELDIR]]></c> is not specified and no
+ <c>-rootdir</c> option is given. Tells start_erl where the
+ root of the release tree is placed in the file-system (typically
+ &lt;Erlang root&gt;\\releases). The
+ <c><![CDATA[start_erl.data]]></c> file is expected to be
+ placed in this directory (if not otherwise specified). If
+ only the <c>-rootdir</c> option is given, the directory is
+ assumed to be &lt;Erlang root&gt;\\releases.</item>
+
+ <tag>-rootdir &lt;Erlang root directory&gt;</tag>
+
+ <item>Mandatory if <c>-reldir</c> is not given and there is
+ no <c><![CDATA[RELDIR]]></c> in the environment. This
+ specifies the Erlang installation root directory (under
+ which the <c>lib</c>, <c>releases</c> and
+ <c>erts-&lt;Version&gt;</c> directories are placed). If only
+ <c>-reldir</c> (or the environment variable
+ <c><![CDATA[RELDIR]]></c>) is given, the Erlang root is assumed to
+ be the directory exactly one level above the release
+ directory.</item>
+
<tag>-data &lt;data file name&gt;</tag>
<item>Optional, specifies another data file than start_erl.data
in the &lt;release root&gt;. It is specified relative to the
diff --git a/erts/doc/src/zlib.xml b/erts/doc/src/zlib.xml
index 47a649af02..8917ab5c3a 100644
--- a/erts/doc/src/zlib.xml
+++ b/erts/doc/src/zlib.xml
@@ -378,31 +378,31 @@ unpack(Z, Compressed, Dict) ->
<name name="crc32" arity="2"/>
<fsummary>Calculate CRC</fsummary>
<desc>
- <p>Calculate the CRC checksum for <c><anno>Binary</anno></c>.</p>
+ <p>Calculate the CRC checksum for <c><anno>Data</anno></c>.</p>
</desc>
</func>
<func>
<name name="crc32" arity="3"/>
<fsummary>Calculate CRC</fsummary>
<desc>
- <p>Update a running CRC checksum for <c><anno>Binary</anno></c>.
- If <c><anno>Binary</anno></c> is the empty binary, this function returns
+ <p>Update a running CRC checksum for <c><anno>Data</anno></c>.
+ If <c><anno>Data</anno></c> is the empty binary or the empty iolist, this function returns
the required initial value for the crc.</p>
<pre>
-Crc = lists:foldl(fun(Bin,Crc0) ->
- zlib:crc32(Z, Crc0, Bin),
- end, zlib:crc32(Z,&lt;&lt; &gt;&gt;), Bins)</pre>
+Crc = lists:foldl(fun(Data,Crc0) ->
+ zlib:crc32(Z, Crc0, Data),
+ end, zlib:crc32(Z,&lt;&lt; &gt;&gt;), Datas)</pre>
</desc>
</func>
<func>
<name name="crc32_combine" arity="4"/>
<fsummary>Combine two CRC's</fsummary>
<desc>
- <p>Combine two CRC checksums into one. For two binaries,
- <c>Bin1</c> and <c>Bin2</c> with sizes of <c>Size1</c> and
+ <p>Combine two CRC checksums into one. For two binaries or iolists,
+ <c>Data1</c> and <c>Data2</c> with sizes of <c>Size1</c> and
<c><anno>Size2</anno></c>, with CRC checksums <c><anno>CRC1</anno></c> and
<c><anno>CRC2</anno></c>. <c>crc32_combine/4</c> returns the <c><anno>CRC</anno></c>
- checksum of <c>&lt;&lt;Bin1/binary,Bin2/binary&gt;&gt;</c>, requiring
+ checksum of <c>[Data1,Data2]</c>, requiring
only <c><anno>CRC1</anno></c>, <c><anno>CRC2</anno></c>, and <c><anno>Size2</anno></c>.
</p>
</desc>
@@ -411,75 +411,75 @@ Crc = lists:foldl(fun(Bin,Crc0) ->
<name name="adler32" arity="2"/>
<fsummary>Calculate the adler checksum</fsummary>
<desc>
- <p>Calculate the Adler-32 checksum for <c><anno>Binary</anno></c>.</p>
+ <p>Calculate the Adler-32 checksum for <c><anno>Data</anno></c>.</p>
</desc>
</func>
<func>
<name name="adler32" arity="3"/>
<fsummary>Calculate the adler checksum</fsummary>
<desc>
- <p>Update a running Adler-32 checksum for <c><anno>Binary</anno></c>.
- If <c><anno>Binary</anno></c> is the empty binary, this function returns
+ <p>Update a running Adler-32 checksum for <c><anno>Data</anno></c>.
+ If <c><anno>Data</anno></c> is the empty binary or the empty iolist, this function returns
the required initial value for the checksum.</p>
<pre>
-Crc = lists:foldl(fun(Bin,Crc0) ->
- zlib:adler32(Z, Crc0, Bin),
- end, zlib:adler32(Z,&lt;&lt; &gt;&gt;), Bins)</pre>
+Crc = lists:foldl(fun(Data,Crc0) ->
+ zlib:adler32(Z, Crc0, Data),
+ end, zlib:adler32(Z,&lt;&lt; &gt;&gt;), Datas)</pre>
</desc>
</func>
<func>
<name name="adler32_combine" arity="4"/>
<fsummary>Combine two Adler-32 checksums</fsummary>
<desc>
- <p>Combine two Adler-32 checksums into one. For two binaries,
- <c>Bin1</c> and <c>Bin2</c> with sizes of <c>Size1</c> and
+ <p>Combine two Adler-32 checksums into one. For two binaries or iolists,
+ <c>Data1</c> and <c>Data2</c> with sizes of <c>Size1</c> and
<c><anno>Size2</anno></c>, with Adler-32 checksums <c><anno>Adler1</anno></c> and
<c><anno>Adler2</anno></c>. <c>adler32_combine/4</c> returns the <c><anno>Adler</anno></c>
- checksum of <c>&lt;&lt;Bin1/binary,Bin2/binary&gt;&gt;</c>, requiring
+ checksum of <c>[Data1,Data2]</c>, requiring
only <c><anno>Adler1</anno></c>, <c><anno>Adler2</anno></c>, and <c><anno>Size2</anno></c>.
</p>
</desc>
</func>
<func>
<name name="compress" arity="1"/>
- <fsummary>Compress a binary with standard zlib functionality</fsummary>
+ <fsummary>Compress data with standard zlib functionality</fsummary>
<desc>
- <p>Compress a binary (with zlib headers and checksum).</p>
+ <p>Compress data (with zlib headers and checksum).</p>
</desc>
</func>
<func>
<name name="uncompress" arity="1"/>
- <fsummary>Uncompress a binary with standard zlib functionality</fsummary>
+ <fsummary>Uncompress data with standard zlib functionality</fsummary>
<desc>
- <p>Uncompress a binary (with zlib headers and checksum).</p>
+ <p>Uncompress data (with zlib headers and checksum).</p>
</desc>
</func>
<func>
<name name="zip" arity="1"/>
- <fsummary>Compress a binary without the zlib headers</fsummary>
+ <fsummary>Compress data without the zlib headers</fsummary>
<desc>
- <p>Compress a binary (without zlib headers and checksum).</p>
+ <p>Compress data (without zlib headers and checksum).</p>
</desc>
</func>
<func>
<name name="unzip" arity="1"/>
- <fsummary>Uncompress a binary without the zlib headers</fsummary>
+ <fsummary>Uncompress data without the zlib headers</fsummary>
<desc>
- <p>Uncompress a binary (without zlib headers and checksum).</p>
+ <p>Uncompress data (without zlib headers and checksum).</p>
</desc>
</func>
<func>
<name name="gzip" arity="1"/>
- <fsummary>Compress a binary with gz header</fsummary>
+ <fsummary>Compress data with gz header</fsummary>
<desc>
- <p>Compress a binary (with gz headers and checksum).</p>
+ <p>Compress data (with gz headers and checksum).</p>
</desc>
</func>
<func>
<name name="gunzip" arity="1"/>
- <fsummary>Uncompress a binary with gz header</fsummary>
+ <fsummary>Uncompress data with gz header</fsummary>
<desc>
- <p>Uncompress a binary (with gz headers and checksum).</p>
+ <p>Uncompress data (with gz headers and checksum).</p>
</desc>
</func>
</funcs>
diff --git a/erts/emulator/Makefile.in b/erts/emulator/Makefile.in
index b658e79378..620402fbfb 100644
--- a/erts/emulator/Makefile.in
+++ b/erts/emulator/Makefile.in
@@ -598,11 +598,6 @@ INCLUDES += -I$(ERL_TOP)/erts/etc/vxworks
endif
ifeq ($(TARGET),win32)
-# Usually the same as the default rule, but certain platforms (i.e. win32) mix
-# different compilers
-$(OBJDIR)/beam_emu.o: beam/beam_emu.c
- $(EMU_CC) $(subst -O2, $(GEN_OPT_FLGS), $(CFLAGS)) $(INCLUDES) -c $< -o $@
-
$(OBJDIR)/dll_sys.o: sys/$(ERLANG_OSTYPE)/sys.c
$(CC) $(CFLAGS) -DERL_RUN_SHARED_LIB=1 $(INCLUDES) -c $< -o $@
@@ -616,6 +611,11 @@ $(OBJDIR)/beam_emu.o: beam/beam_emu.c
$(CC) $(subst -O2, $(GEN_OPT_FLGS), $(CFLAGS)) \
-OPT:Olimit=0 -WOPT:lpre=off:spre=off:epre=off \
$(INCLUDES) -c $< -o $@
+else
+# Usually the same as the default rule, but certain platforms (e.g. win32) mix
+# different compilers
+$(OBJDIR)/beam_emu.o: beam/beam_emu.c
+ $(EMU_CC) $(subst -O2, $(GEN_OPT_FLGS), $(CFLAGS)) $(INCLUDES) -c $< -o $@
endif
diff --git a/erts/emulator/beam/beam_bif_load.c b/erts/emulator/beam/beam_bif_load.c
index d76a7d8e9f..2561d7a630 100644
--- a/erts/emulator/beam/beam_bif_load.c
+++ b/erts/emulator/beam/beam_bif_load.c
@@ -162,6 +162,23 @@ BIF_RETTYPE code_make_stub_module_3(BIF_ALIST_3)
return res;
}
+BIF_RETTYPE
+check_old_code_1(BIF_ALIST_1)
+{
+ Module* modp;
+
+ if (is_not_atom(BIF_ARG_1)) {
+ BIF_ERROR(BIF_P, BADARG);
+ }
+ modp = erts_get_module(BIF_ARG_1);
+ if (modp == NULL) { /* Doesn't exist. */
+ BIF_RET(am_false);
+ } else if (modp->old_code == NULL) { /* No old code. */
+ BIF_RET(am_false);
+ }
+ BIF_RET(am_true);
+}
+
Eterm
check_process_code_2(BIF_ALIST_2)
{
@@ -175,6 +192,13 @@ check_process_code_2(BIF_ALIST_2)
Eterm res;
if (internal_pid_index(BIF_ARG_1) >= erts_max_processes)
goto error;
+ modp = erts_get_module(BIF_ARG_2);
+ if (modp == NULL) { /* Doesn't exist. */
+ return am_false;
+ } else if (modp->old_code == NULL) { /* No old code. */
+ return am_false;
+ }
+
#ifdef ERTS_SMP
rp = erts_pid2proc_suspend(BIF_P, ERTS_PROC_LOCK_MAIN,
BIF_ARG_1, ERTS_PROC_LOCK_MAIN);
@@ -188,7 +212,6 @@ check_process_code_2(BIF_ALIST_2)
ERTS_BIF_YIELD2(bif_export[BIF_check_process_code_2], BIF_P,
BIF_ARG_1, BIF_ARG_2);
}
- modp = erts_get_module(BIF_ARG_2);
res = check_process_code(rp, modp);
#ifdef ERTS_SMP
if (BIF_P != rp) {
@@ -412,11 +435,6 @@ check_process_code(Process* rp, Module* modp)
#endif
#define INSIDE(a) (start <= (a) && (a) < end)
- if (modp == NULL) { /* Doesn't exist. */
- return am_false;
- } else if (modp->old_code == NULL) { /* No old code. */
- return am_false;
- }
/*
* Pick up limits for the module.
diff --git a/erts/emulator/beam/bif.tab b/erts/emulator/beam/bif.tab
index d9dd80fa8b..831c0b1ce6 100644
--- a/erts/emulator/beam/bif.tab
+++ b/erts/emulator/beam/bif.tab
@@ -87,6 +87,8 @@ bif erlang:exit/2
bif 'erl.lang.proc':signal/2 ebif_signal_2 exit_2
bif erlang:external_size/1
bif 'erl.lang.term':external_size/1 ebif_external_size_1
+bif erlang:external_size/2
+bif 'erl.lang.term':external_size/2 ebif_external_size_2
ubif erlang:float/1
ubif 'erl.lang.number':to_float/1 ebif_to_float_1 float_1
bif erlang:float_to_list/1
@@ -802,6 +804,12 @@ bif prim_file:internal_name2native/1
bif prim_file:internal_native2name/1
bif prim_file:internal_normalize_utf8/1
bif file:native_name_encoding/0
+
+#
+# New in R14B04.
+#
+bif erlang:check_old_code/1
+
#
# Obsolete
#
diff --git a/erts/emulator/beam/erl_bif_trace.c b/erts/emulator/beam/erl_bif_trace.c
index 0509e51a6f..fbd8757751 100644
--- a/erts/emulator/beam/erl_bif_trace.c
+++ b/erts/emulator/beam/erl_bif_trace.c
@@ -679,7 +679,7 @@ trace_3(Process* p, Eterm pid_spec, Eterm how, Eterm list)
} else if (tracer != NIL) {
tracee_port->tracer_proc = tracer;
}
- /* matches are not counted for ports since it would violate compability */
+ /* matches are not counted for ports since it would violate compatibility */
/* This could be a reason to modify this function or make a new one. */
}
}
diff --git a/erts/emulator/beam/erl_db.c b/erts/emulator/beam/erl_db.c
index eb50f56502..e9bdeb35ef 100644
--- a/erts/emulator/beam/erl_db.c
+++ b/erts/emulator/beam/erl_db.c
@@ -3658,9 +3658,6 @@ static Eterm table_info(Process* p, DbTable* tb, Eterm What)
ret = am_true;
else
ret = am_false;
- } else if (What == am_atom_put("kept_objects",12)) {
- ret = make_small(IS_HASH_TABLE(tb->common.status)
- ? db_kept_items_hash(&tb->hash) : 0);
} else if (What == am_atom_put("safe_fixed",10)) {
#ifdef ERTS_SMP
erts_smp_mtx_lock(&tb->common.fixlock);
@@ -3702,7 +3699,7 @@ static Eterm table_info(Process* p, DbTable* tb, Eterm What)
Eterm* hp;
db_calc_stats_hash(&tb->hash, &stats);
- hp = HAlloc(p, 1 + 6 + FLOAT_SIZE_OBJECT*3);
+ hp = HAlloc(p, 1 + 7 + FLOAT_SIZE_OBJECT*3);
f.fd = stats.avg_chain_len;
avg = make_float(hp);
PUT_DOUBLE(f, hp);
@@ -3717,10 +3714,11 @@ static Eterm table_info(Process* p, DbTable* tb, Eterm What)
std_dev_exp = make_float(hp);
PUT_DOUBLE(f, hp);
hp += FLOAT_SIZE_OBJECT;
- ret = TUPLE6(hp, make_small(erts_smp_atomic_read(&tb->hash.nactive)),
+ ret = TUPLE7(hp, make_small(erts_smp_atomic_read(&tb->hash.nactive)),
avg, std_dev_real, std_dev_exp,
make_small(stats.min_chain_len),
- make_small(stats.max_chain_len));
+ make_small(stats.max_chain_len),
+ make_small(db_kept_items_hash(&tb->hash)));
}
else {
ret = am_false;
diff --git a/erts/emulator/beam/erl_gc.c b/erts/emulator/beam/erl_gc.c
index 5edcd667e7..e3445bcdc5 100644
--- a/erts/emulator/beam/erl_gc.c
+++ b/erts/emulator/beam/erl_gc.c
@@ -100,14 +100,14 @@ static Uint combined_message_size(Process* p);
static void remove_message_buffers(Process* p);
static int major_collection(Process* p, int need, Eterm* objv, int nobj, Uint *recl);
static int minor_collection(Process* p, int need, Eterm* objv, int nobj, Uint *recl);
-static void do_minor(Process *p, int new_sz, Eterm* objv, int nobj);
+static void do_minor(Process *p, Uint new_sz, Eterm* objv, int nobj);
static Eterm* sweep_rootset(Rootset *rootset, Eterm* htop, char* src, Uint src_size);
static Eterm* sweep_one_area(Eterm* n_hp, Eterm* n_htop, char* src, Uint src_size);
static Eterm* sweep_one_heap(Eterm* heap_ptr, Eterm* heap_end, Eterm* htop,
char* src, Uint src_size);
static Eterm* collect_heap_frags(Process* p, Eterm* heap,
Eterm* htop, Eterm* objv, int nobj);
-static Uint adjust_after_fullsweep(Process *p, int size_before,
+static Uint adjust_after_fullsweep(Process *p, Uint size_before,
int need, Eterm *objv, int nobj);
static void shrink_new_heap(Process *p, Uint new_sz, Eterm *objv, int nobj);
static void grow_new_heap(Process *p, Uint new_sz, Eterm* objv, int nobj);
@@ -441,7 +441,15 @@ erts_garbage_collect(Process* p, int need, Eterm* objv, int nobj)
p->last_old_htop = p->old_htop;
#endif
- return ((int) (HEAP_TOP(p) - HEAP_START(p)) / 10);
+ /* FIXME: This function should really return an Sint, i.e., a possibly
+ 64 bit wide signed integer, but that requires updating all the code
+ that calls it. For now, we just return INT_MAX if the result is too
+ large for an int. */
+ {
+ Sint result = (HEAP_TOP(p) - HEAP_START(p)) / 10;
+ if (result >= INT_MAX) return INT_MAX;
+ else return (int) result;
+ }
}
/*
@@ -599,7 +607,7 @@ erts_garbage_collect_literals(Process* p, Eterm* literals, Uint lit_size)
char* area;
Uint area_size;
Eterm* old_htop;
- int n;
+ Uint n;
/*
* Set GC state.
@@ -731,7 +739,7 @@ minor_collection(Process* p, int need, Eterm* objv, int nobj, Uint *recl)
* This improved Estone by more than 1200 estones on my computer
* (Ultra Sparc 10).
*/
- size_t new_sz = erts_next_heap_size(HEAP_TOP(p) - HEAP_START(p), 1);
+ Uint new_sz = erts_next_heap_size(HEAP_TOP(p) - HEAP_START(p), 1);
/* Create new, empty old_heap */
n_old = (Eterm *) ERTS_HEAP_ALLOC(ERTS_ALC_T_OLD_HEAP,
@@ -871,12 +879,12 @@ minor_collection(Process* p, int need, Eterm* objv, int nobj, Uint *recl)
#endif /* HIPE */
static void
-do_minor(Process *p, int new_sz, Eterm* objv, int nobj)
+do_minor(Process *p, Uint new_sz, Eterm* objv, int nobj)
{
Rootset rootset; /* Rootset for GC (stack, dictionary, etc). */
Roots* roots;
Eterm* n_htop;
- int n;
+ Uint n;
Eterm* ptr;
Eterm val;
Eterm gval;
@@ -1079,14 +1087,14 @@ major_collection(Process* p, int need, Eterm* objv, int nobj, Uint *recl)
{
Rootset rootset;
Roots* roots;
- int size_before;
+ Uint size_before;
Eterm* n_heap;
Eterm* n_htop;
char* src = (char *) HEAP_START(p);
Uint src_size = (char *) HEAP_TOP(p) - src;
char* oh = (char *) OLD_HEAP(p);
Uint oh_size = (char *) OLD_HTOP(p) - oh;
- int n;
+ Uint n;
Uint new_sz;
Uint fragments = MBUF_SIZE(p) + combined_message_size(p);
ErlMessage *msgp;
@@ -1312,10 +1320,10 @@ major_collection(Process* p, int need, Eterm* objv, int nobj, Uint *recl)
}
static Uint
-adjust_after_fullsweep(Process *p, int size_before, int need, Eterm *objv, int nobj)
+adjust_after_fullsweep(Process *p, Uint size_before, int need, Eterm *objv, int nobj)
{
- int wanted, sz, size_after, need_after;
- int stack_size = STACK_SZ_ON_HEAP(p);
+ Uint wanted, sz, size_after, need_after;
+ Uint stack_size = STACK_SZ_ON_HEAP(p);
Uint reclaimed_now;
size_after = (HEAP_TOP(p) - HEAP_START(p));
@@ -1915,8 +1923,8 @@ static void
grow_new_heap(Process *p, Uint new_sz, Eterm* objv, int nobj)
{
Eterm* new_heap;
- int heap_size = HEAP_TOP(p) - HEAP_START(p);
- int stack_size = p->hend - p->stop;
+ Uint heap_size = HEAP_TOP(p) - HEAP_START(p);
+ Uint stack_size = p->hend - p->stop;
Sint offs;
ASSERT(HEAP_SIZE(p) < new_sz);
@@ -1954,10 +1962,10 @@ static void
shrink_new_heap(Process *p, Uint new_sz, Eterm *objv, int nobj)
{
Eterm* new_heap;
- int heap_size = HEAP_TOP(p) - HEAP_START(p);
+ Uint heap_size = HEAP_TOP(p) - HEAP_START(p);
Sint offs;
- int stack_size = p->hend - p->stop;
+ Uint stack_size = p->hend - p->stop;
ASSERT(new_sz < p->heap_sz);
sys_memmove(p->heap + new_sz - stack_size, p->stop, stack_size *
diff --git a/erts/emulator/beam/erl_init.c b/erts/emulator/beam/erl_init.c
index 0a57eb6d88..0173fd40f6 100644
--- a/erts/emulator/beam/erl_init.c
+++ b/erts/emulator/beam/erl_init.c
@@ -803,10 +803,12 @@ early_init(int *argc, char **argv) /*
#if defined(HIPE)
hipe_signal_init(); /* must be done very early */
#endif
- erl_sys_init();
erl_sys_args(argc, argv);
+ /* Creates threads on Windows that depend on the arguments, so has to be after erl_sys_args */
+ erl_sys_init();
+
erts_ets_realloc_always_moves = 0;
erts_ets_always_compress = 0;
erts_dist_buf_busy_limit = ERTS_DE_BUSY_LIMIT;
diff --git a/erts/emulator/beam/erl_nif.c b/erts/emulator/beam/erl_nif.c
index d9b1a8e89d..6e7ac43676 100644
--- a/erts/emulator/beam/erl_nif.c
+++ b/erts/emulator/beam/erl_nif.c
@@ -578,7 +578,15 @@ int enif_is_identical(Eterm lhs, Eterm rhs)
int enif_compare(Eterm lhs, Eterm rhs)
{
- return CMP(lhs,rhs);
+ Sint result = CMP(lhs,rhs);
+
+ if (result < 0) {
+ return -1;
+ } else if (result > 0) {
+ return 1;
+ }
+
+ return result;
}
int enif_get_tuple(ErlNifEnv* env, Eterm tpl, int* arity, const Eterm** array)
diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c
index 2704359a8f..d8aed63544 100644
--- a/erts/emulator/beam/erl_process.c
+++ b/erts/emulator/beam/erl_process.c
@@ -5782,10 +5782,13 @@ erts_sched_stat_term(Process *p, int total)
void
erts_schedule_misc_op(void (*func)(void *), void *arg)
{
- ErtsRunQueue *rq = erts_get_runq_current(NULL);
+ ErtsRunQueue *rq;
ErtsMiscOpList *molp = misc_op_list_alloc();
+ ErtsSchedulerData *esdp = erts_get_scheduler_data();
- if (!rq) {
+ if (esdp) {
+ rq = esdp->run_queue;
+ } else {
/*
* This can only happen when the sys msg dispatcher
* thread schedules misc ops (this happens *very*
diff --git a/erts/emulator/beam/erl_threads.h b/erts/emulator/beam/erl_threads.h
index 8c9cace0c5..a0eda61ba5 100644
--- a/erts/emulator/beam/erl_threads.h
+++ b/erts/emulator/beam/erl_threads.h
@@ -571,8 +571,9 @@ erts_mtx_destroy(erts_mtx_t *mtx)
"Most likely a bug in pthread implementation.";
erts_send_warning_to_logger_str_nogl(warn);
}
+ else
#endif
- erts_thr_fatal_error(res, "destroy mutex");
+ erts_thr_fatal_error(res, "destroy mutex");
}
#endif
}
@@ -675,8 +676,9 @@ erts_cnd_destroy(erts_cnd_t *cnd)
"Most likely a bug in pthread implementation.";
erts_send_warning_to_logger_str_nogl(warn);
}
+ else
#endif
- erts_thr_fatal_error(res, "destroy condition variable");
+ erts_thr_fatal_error(res, "destroy condition variable");
}
#endif
}
@@ -810,8 +812,9 @@ erts_rwmtx_destroy(erts_rwmtx_t *rwmtx)
"Most likely a bug in pthread implementation.";
erts_send_warning_to_logger_str_nogl(warn);
}
+ else
#endif
- erts_thr_fatal_error(res, "destroy rwmutex");
+ erts_thr_fatal_error(res, "destroy rwmutex");
}
#endif
}
@@ -1496,8 +1499,9 @@ erts_spinlock_destroy(erts_spinlock_t *lock)
"Most likely a bug in pthread implementation.";
erts_send_warning_to_logger_str_nogl(warn);
}
+ else
#endif
- erts_thr_fatal_error(res, "destroy rwlock");
+ erts_thr_fatal_error(res, "destroy rwlock");
}
#else
(void)lock;
@@ -1614,8 +1618,9 @@ erts_rwlock_destroy(erts_rwlock_t *lock)
"Most likely a bug in pthread implementation.";
erts_send_warning_to_logger_str_nogl(warn);
}
+ else
#endif
- erts_thr_fatal_error(res, "destroy rwlock");
+ erts_thr_fatal_error(res, "destroy rwlock");
}
#else
(void)lock;
diff --git a/erts/emulator/beam/external.c b/erts/emulator/beam/external.c
index 1a102f7187..6953e7fe7d 100644
--- a/erts/emulator/beam/external.c
+++ b/erts/emulator/beam/external.c
@@ -459,6 +459,12 @@ Uint erts_encode_ext_size(Eterm term)
+ 1 /* VERSION_MAGIC */;
}
+Uint erts_encode_ext_size_2(Eterm term, unsigned dflags)
+{
+ return encode_size_struct2(NULL, term, TERM_TO_BINARY_DFLAGS|dflags)
+ + 1 /* VERSION_MAGIC */;
+}
+
Uint erts_encode_ext_size_ets(Eterm term)
{
return encode_size_struct2(NULL, term, TERM_TO_BINARY_DFLAGS|DFLAGS_INTERNAL_TAGS);
@@ -1262,6 +1268,49 @@ external_size_1(Process* p, Eterm Term)
}
Eterm
+external_size_2(Process* p, Eterm Term, Eterm Flags)
+{
+ Uint size;
+ Uint flags = TERM_TO_BINARY_DFLAGS;
+
+ while (is_list(Flags)) {
+ Eterm arg = CAR(list_val(Flags));
+ Eterm* tp;
+
+ if (is_tuple(arg) && *(tp = tuple_val(arg)) == make_arityval(2)) {
+ if (tp[1] == am_minor_version && is_small(tp[2])) {
+ switch (signed_val(tp[2])) {
+ case 0:
+ break;
+ case 1:
+ flags |= DFLAG_NEW_FLOATS;
+ break;
+ default:
+ goto error;
+ }
+ } else {
+ goto error;
+ }
+ } else {
+ error:
+ BIF_ERROR(p, BADARG);
+ }
+ Flags = CDR(list_val(Flags));
+ }
+ if (is_not_nil(Flags)) {
+ goto error;
+ }
+
+ size = erts_encode_ext_size_2(Term, flags);
+ if (IS_USMALL(0, size)) {
+ BIF_RET(make_small(size));
+ } else {
+ Eterm* hp = HAlloc(p, BIG_UINT_HEAP_SIZE);
+ BIF_RET(uint_to_big(size, hp));
+ }
+}
+
+Eterm
erts_term_to_binary(Process* p, Eterm Term, int level, Uint flags)
{
Uint size;
diff --git a/erts/emulator/beam/external.h b/erts/emulator/beam/external.h
index d8287b96a4..72fe74baf2 100644
--- a/erts/emulator/beam/external.h
+++ b/erts/emulator/beam/external.h
@@ -160,6 +160,7 @@ Uint erts_encode_dist_ext_size(Eterm, Uint32, ErtsAtomCacheMap *);
void erts_encode_dist_ext(Eterm, byte **, Uint32, ErtsAtomCacheMap *);
Uint erts_encode_ext_size(Eterm);
+Uint erts_encode_ext_size_2(Eterm, unsigned);
Uint erts_encode_ext_size_ets(Eterm);
void erts_encode_ext(Eterm, byte **);
byte* erts_encode_ext_ets(Eterm, byte *, struct erl_off_heap_header** ext_off_heap);
diff --git a/erts/emulator/drivers/common/inet_drv.c b/erts/emulator/drivers/common/inet_drv.c
index ebc4469a23..743c01d935 100644
--- a/erts/emulator/drivers/common/inet_drv.c
+++ b/erts/emulator/drivers/common/inet_drv.c
@@ -7012,7 +7012,7 @@ static int sctp_fill_opts(inet_descriptor* desc, char* buf, int buflen,
default:
RETURN_ERROR(spec, -EINVAL); /* No more valid options */
}
- /* If we get here one result has been succesfully loaded */
+ /* If we get here one result has been successfully loaded */
length ++;
}
if (buflen != 0) RETURN_ERROR(spec, -EINVAL); /* Optparam mismatch */
diff --git a/erts/emulator/drivers/win32/win_efile.c b/erts/emulator/drivers/win32/win_efile.c
index 3d59564f7b..931bb196f1 100755
--- a/erts/emulator/drivers/win32/win_efile.c
+++ b/erts/emulator/drivers/win32/win_efile.c
@@ -127,6 +127,8 @@ static int errno_map(DWORD last_error) {
return EBUSY;
case ERROR_NO_PROC_SLOTS:
return EAGAIN;
+ case ERROR_CANT_RESOLVE_FILENAME:
+ return EMLINK;
case ERROR_ARENA_TRASHED:
case ERROR_INVALID_BLOCK:
case ERROR_BAD_ENVIRONMENT:
@@ -1405,7 +1407,7 @@ efile_readlink(Efile_error* errInfo, char* name, char* buffer, size_t size)
DWORD fileAttributes = GetFileAttributesW(wname);
if ((fileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) {
BOOLEAN success = 0;
- HANDLE h = CreateFileW(wname, GENERIC_READ, 0,NULL, OPEN_EXISTING, 0, NULL);
+ HANDLE h = CreateFileW(wname, GENERIC_READ, 0,NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
int len;
if(h != INVALID_HANDLE_VALUE) {
success = pGetFinalPathNameByHandle(h, wbuffer, size,0);
@@ -1421,7 +1423,7 @@ efile_readlink(Efile_error* errInfo, char* name, char* buffer, size_t size)
if (*wbuffer == L'\\')
*wbuffer = L'/';
CloseHandle(h);
- }
+ }
FreeLibrary(hModule);
if (success) {
return 1;
diff --git a/erts/emulator/sys/common/erl_poll.c b/erts/emulator/sys/common/erl_poll.c
index f5c785d683..7278075f54 100644
--- a/erts/emulator/sys/common/erl_poll.c
+++ b/erts/emulator/sys/common/erl_poll.c
@@ -405,7 +405,7 @@ woke_up(ErtsPollSet ps)
static ERTS_INLINE void
wake_poller(ErtsPollSet ps, int interrupted)
{
- int wake;
+ int wake = 0;
#ifdef ERTS_SMP
erts_aint32_t wakeup_state;
if (!interrupted)
diff --git a/erts/emulator/sys/unix/sys.c b/erts/emulator/sys/unix/sys.c
index bafbbb0f6c..e5ee0df7fa 100644
--- a/erts/emulator/sys/unix/sys.c
+++ b/erts/emulator/sys/unix/sys.c
@@ -527,7 +527,6 @@ erts_sys_pre_init(void)
void
erl_sys_init(void)
{
- erts_smp_rwmtx_init(&environ_rwmtx, "environ");
#if !DISABLE_VFORK
{
int res;
@@ -3090,6 +3089,8 @@ erl_sys_args(int* argc, char** argv)
{
int i, j;
+ erts_smp_rwmtx_init(&environ_rwmtx, "environ");
+
i = 1;
ASSERT(argc && argv);
@@ -3151,4 +3152,5 @@ erl_sys_args(int* argc, char** argv)
argv[j++] = argv[i];
}
*argc = j;
+
}
diff --git a/erts/emulator/sys/win32/sys.c b/erts/emulator/sys/win32/sys.c
index a2159d063c..c8075c1916 100644
--- a/erts/emulator/sys/win32/sys.c
+++ b/erts/emulator/sys/win32/sys.c
@@ -2771,7 +2771,7 @@ ready_output(ErlDrvData drv_data, ErlDrvEvent ready_event)
DEBUGF(("ready_output(%d, 0x%x)\n", drv_data, ready_event));
set_busy_port(dp->port_num, 0);
if (!(dp->outbuf)) {
- /* Happens because event sometimes get signalled during a succesful
+ /* Happens because event sometimes get signalled during a successful
write... */
return;
}
@@ -3282,6 +3282,7 @@ erts_sys_pre_init(void)
}
#endif
erts_smp_atomic_init(&sys_misc_mem_sz, 0);
+ erts_sys_env_init();
}
void noinherit_std_handle(DWORD type)
@@ -3297,8 +3298,6 @@ void erl_sys_init(void)
{
HANDLE handle;
- erts_sys_env_init();
-
noinherit_std_handle(STD_OUTPUT_HANDLE);
noinherit_std_handle(STD_INPUT_HANDLE);
noinherit_std_handle(STD_ERROR_HANDLE);
diff --git a/erts/emulator/test/binary_SUITE.erl b/erts/emulator/test/binary_SUITE.erl
index 4e82381fba..fed5854112 100644
--- a/erts/emulator/test/binary_SUITE.erl
+++ b/erts/emulator/test/binary_SUITE.erl
@@ -478,6 +478,11 @@ terms(Config) when is_list(Config) ->
Sz when is_integer(Sz), size(Bin) =< Sz ->
ok
end,
+ Bin1 = term_to_binary(Term, [{minor_version, 1}]),
+ case erlang:external_size(Bin1, [{minor_version, 1}]) of
+ Sz1 when is_integer(Sz1), size(Bin1) =< Sz1 ->
+ ok
+ end,
Term = binary_to_term(Bin),
Term = binary_to_term(Bin, [safe]),
Unaligned = make_unaligned_sub_binary(Bin),
@@ -510,7 +515,12 @@ terms_float(Config) when is_list(Config) ->
Term = binary_to_term(Bin0),
Bin1 = term_to_binary(Term, [{minor_version,1}]),
Term = binary_to_term(Bin1),
- true = size(Bin1) < size(Bin0)
+ true = size(Bin1) < size(Bin0),
+ Size0 = erlang:external_size(Term),
+ Size00 = erlang:external_size(Term, [{minor_version, 0}]),
+ Size1 = erlang:external_size(Term, [{minor_version, 1}]),
+ true = (Size0 =:= Size00),
+ true = Size1 < Size0
end).
external_size(Config) when is_list(Config) ->
@@ -526,7 +536,9 @@ external_size(Config) when is_list(Config) ->
io:format(" Aligned size: ~p\n", [Sz1]),
io:format("Unaligned size: ~p\n", [Sz2]),
?line ?t:fail()
- end.
+ end,
+ ?line erlang:external_size(Bin) =:= erlang:external_size(Bin, [{minor_version, 1}]),
+ ?line erlang:external_size(Unaligned) =:= erlang:external_size(Unaligned, [{minor_version, 1}]).
external_size_1(Term, Size0, Limit) when Size0 < Limit ->
case erlang:external_size(Term) of
diff --git a/erts/emulator/test/code_SUITE.erl b/erts/emulator/test/code_SUITE.erl
index a062cea117..29cbdedd17 100644
--- a/erts/emulator/test/code_SUITE.erl
+++ b/erts/emulator/test/code_SUITE.erl
@@ -20,7 +20,9 @@
-module(code_SUITE).
-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
init_per_group/2,end_per_group/2,
- new_binary_types/1,t_check_process_code/1,t_check_process_code_ets/1,
+ new_binary_types/1,
+ t_check_process_code/1,t_check_old_code/1,
+ t_check_process_code_ets/1,
external_fun/1,get_chunk/1,module_md5/1,make_stub/1,
make_stub_many_funs/1,constant_pools/1,
false_dependency/1,coverage/1]).
@@ -31,7 +33,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
[new_binary_types, t_check_process_code,
- t_check_process_code_ets, external_fun, get_chunk,
+ t_check_process_code_ets, t_check_old_code, external_fun, get_chunk,
module_md5, make_stub, make_stub_many_funs,
constant_pools, false_dependency, coverage].
@@ -248,6 +250,32 @@ fun_refc(F) ->
Count.
+%% Test the erlang:check_old_code/1 BIF.
+t_check_old_code(Config) when is_list(Config) ->
+ ?line Data = ?config(data_dir, Config),
+ ?line File = filename:join(Data, "my_code_test"),
+
+ ?line erlang:purge_module(my_code_test),
+ ?line erlang:delete_module(my_code_test),
+ ?line catch erlang:purge_module(my_code_test),
+
+ ?line false = erlang:check_old_code(my_code_test),
+
+ ?line {ok,my_code_test,Code} = compile:file(File, [binary]),
+ ?line {module,my_code_test} = code:load_binary(my_code_test, File, Code),
+
+ ?line false = erlang:check_old_code(my_code_test),
+ ?line {module,my_code_test} = code:load_binary(my_code_test, File, Code),
+ ?line true = erlang:check_old_code(my_code_test),
+
+ ?line true = erlang:purge_module(my_code_test),
+ ?line true = erlang:delete_module(my_code_test),
+ ?line true = erlang:purge_module(my_code_test),
+
+ ?line {'EXIT',_} = (catch erlang:check_old_code([])),
+
+ ok.
+
external_fun(Config) when is_list(Config) ->
?line false = erlang:function_exported(another_code_test, x, 1),
?line ExtFun = erlang:make_fun(id(another_code_test), x, 1),
diff --git a/erts/emulator/test/distribution_SUITE.erl b/erts/emulator/test/distribution_SUITE.erl
index 4bebae51cc..e4af5c00a6 100644
--- a/erts/emulator/test/distribution_SUITE.erl
+++ b/erts/emulator/test/distribution_SUITE.erl
@@ -173,7 +173,7 @@ bulk_sendsend(Terms, BinSize) ->
Ratio = if MonitorCount2 == 0 -> MonitorCount1 / 1.0;
true -> MonitorCount1 / MonitorCount2
end,
- %% A somewhat arbitrary ratio, but hopefully one that will accomodate
+ %% A somewhat arbitrary ratio, but hopefully one that will accommodate
%% a wide range of CPU speeds.
true = (Ratio > 8.0),
{comment,
diff --git a/erts/emulator/test/driver_SUITE.erl b/erts/emulator/test/driver_SUITE.erl
index f6cf01ce16..a77ea4f3be 100644
--- a/erts/emulator/test/driver_SUITE.erl
+++ b/erts/emulator/test/driver_SUITE.erl
@@ -1590,7 +1590,7 @@ otp_6879(Config) when is_list(Config) ->
end
end,
Procs),
- %% Also try it when input exeeds default buffer (256 bytes)
+ %% Also try it when input exceeds default buffer (256 bytes)
?line Data = lists:seq(1, 1000),
?line case open_port({spawn, Drv}, []) of
Port when is_port(Port) ->
diff --git a/erts/emulator/test/mtx_SUITE_data/mtx_SUITE.c b/erts/emulator/test/mtx_SUITE_data/mtx_SUITE.c
index 818023211c..0e4065c26b 100644
--- a/erts/emulator/test/mtx_SUITE_data/mtx_SUITE.c
+++ b/erts/emulator/test/mtx_SUITE_data/mtx_SUITE.c
@@ -552,13 +552,19 @@ create_rwlock(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
static ERL_NIF_TERM
rwlock_op(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
{
- rwlock_resource_t *rwlr;
+ /*
+ * Use a union for pointer type conversion to avoid compiler warnings
+ * about strict-aliasing violations with gcc-4.1. gcc >= 4.2 does not
+ * emit the warning.
+ * TODO: Reconsider use of union once gcc-4.1 is obsolete?
+ */
+ union { void* vp; rwlock_resource_t *p; } rwlr;
int blocking, write, wait_locked, wait_unlocked;
if (argc != 5)
goto badarg;
- if (!enif_get_resource(env, argv[0], enif_priv_data(env), (void **) &rwlr))
+ if (!enif_get_resource(env, argv[0], enif_priv_data(env), &rwlr.vp))
goto badarg;
blocking = get_bool(env, argv[1]);
@@ -581,22 +587,22 @@ rwlock_op(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
if (write) {
if (blocking)
- RWMUTEX_WLOCK(rwlr->rwlock);
+ RWMUTEX_WLOCK(rwlr.p->rwlock);
else
- while (EBUSY == RWMUTEX_TRYWLOCK(rwlr->rwlock));
- if (rwlr->lock_check) {
- ASSERT(!ATOMIC_READ(&rwlr->is_locked));
- ATOMIC_SET(&rwlr->is_locked, -1);
+ while (EBUSY == RWMUTEX_TRYWLOCK(rwlr.p->rwlock));
+ if (rwlr.p->lock_check) {
+ ASSERT(!ATOMIC_READ(&rwlr.p->is_locked));
+ ATOMIC_SET(&rwlr.p->is_locked, -1);
}
}
else {
if (blocking)
- RWMUTEX_RLOCK(rwlr->rwlock);
+ RWMUTEX_RLOCK(rwlr.p->rwlock);
else
- while (EBUSY == RWMUTEX_TRYRLOCK(rwlr->rwlock));
- if (rwlr->lock_check) {
- ASSERT(ATOMIC_READ(&rwlr->is_locked) >= 0);
- ATOMIC_INC(&rwlr->is_locked);
+ while (EBUSY == RWMUTEX_TRYRLOCK(rwlr.p->rwlock));
+ if (rwlr.p->lock_check) {
+ ASSERT(ATOMIC_READ(&rwlr.p->is_locked) >= 0);
+ ATOMIC_INC(&rwlr.p->is_locked);
}
}
@@ -604,18 +610,18 @@ rwlock_op(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
milli_sleep(wait_locked);
if (write) {
- if (rwlr->lock_check) {
- ASSERT(ATOMIC_READ(&rwlr->is_locked) == -1);
- ATOMIC_SET(&rwlr->is_locked, 0);
+ if (rwlr.p->lock_check) {
+ ASSERT(ATOMIC_READ(&rwlr.p->is_locked) == -1);
+ ATOMIC_SET(&rwlr.p->is_locked, 0);
}
- RWMUTEX_WUNLOCK(rwlr->rwlock);
+ RWMUTEX_WUNLOCK(rwlr.p->rwlock);
}
else {
- if (rwlr->lock_check) {
- ASSERT(ATOMIC_READ(&rwlr->is_locked) > 0);
- ATOMIC_DEC(&rwlr->is_locked);
+ if (rwlr.p->lock_check) {
+ ASSERT(ATOMIC_READ(&rwlr.p->is_locked) > 0);
+ ATOMIC_DEC(&rwlr.p->is_locked);
}
- RWMUTEX_RUNLOCK(rwlr->rwlock);
+ RWMUTEX_RUNLOCK(rwlr.p->rwlock);
}
if (wait_unlocked)
diff --git a/erts/emulator/test/nif_SUITE.erl b/erts/emulator/test/nif_SUITE.erl
index 2867e8e2e4..f6344791f1 100644
--- a/erts/emulator/test/nif_SUITE.erl
+++ b/erts/emulator/test/nif_SUITE.erl
@@ -281,6 +281,12 @@ types(Config) when is_list(Config) ->
end, int_list()),
?line verify_tmpmem(TmpMem),
+ ?line true = (compare(-1294536544000, -1178704800000) < 0),
+ ?line true = (compare(-1178704800000, -1294536544000) > 0),
+ ?line true = (compare(-295147905179352825856, -36893488147419103232) < 0),
+ ?line true = (compare(-36893488147419103232, -295147905179352825856) > 0),
+ ?line true = (compare(-29514790517935282585612345678, -36893488147419103232) < 0),
+ ?line true = (compare(-36893488147419103232, -29514790517935282585612345678) > 0),
ok.
int_list() ->
diff --git a/erts/emulator/test/nif_SUITE_data/nif_SUITE.c b/erts/emulator/test/nif_SUITE_data/nif_SUITE.c
index 00a1365bc3..92f1bab8dd 100644
--- a/erts/emulator/test/nif_SUITE_data/nif_SUITE.c
+++ b/erts/emulator/test/nif_SUITE_data/nif_SUITE.c
@@ -41,7 +41,18 @@ typedef struct
CallInfo* call_history;
NifModPrivData* nif_mod;
union { ErlNifResourceType* t; long l; } rt_arr[2];
-}PrivData;
+} PrivData;
+
+/*
+ * Use a union for pointer type conversion to avoid compiler warnings
+ * about strict-aliasing violations with gcc-4.1. gcc >= 4.2 does not
+ * emit the warning.
+ * TODO: Reconsider use of union once gcc-4.1 is obsolete?
+ */
+typedef union {
+ void* vp;
+ struct make_term_info* p;
+} mti_t;
void add_call(ErlNifEnv* env, PrivData* data, const char* func_name)
{
@@ -707,7 +718,7 @@ static ERL_NIF_TERM get_resource_type(ErlNifEnv* env, int argc, const ERL_NIF_TE
static ERL_NIF_TERM alloc_resource(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
ErlNifBinary data_bin;
- union { ErlNifResourceType* t; long l;} type;
+ union { ErlNifResourceType* t; long l; } type;
union { void* p; long l;} data;
if (!enif_get_long(env, argv[0], &type.l)
|| !enif_inspect_binary(env, argv[1], &data_bin)
@@ -731,7 +742,7 @@ static ERL_NIF_TERM make_resource(ErlNifEnv* env, int argc, const ERL_NIF_TERM a
static ERL_NIF_TERM make_new_resource(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
ErlNifBinary data_bin;
- union { ErlNifResourceType* t; long l;} type;
+ union { ErlNifResourceType* t; long l; } type;
void* data;
ERL_NIF_TERM ret;
if (!enif_get_long(env, argv[0], &type.l)
@@ -749,7 +760,7 @@ static ERL_NIF_TERM make_new_resource(ErlNifEnv* env, int argc, const ERL_NIF_TE
static ERL_NIF_TERM make_new_resource_binary(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
ErlNifBinary data_bin;
- union { struct binary_resource* p; void* vp; long l;} br;
+ union { struct binary_resource* p; void* vp; long l; } br;
void* buf;
ERL_NIF_TERM ret;
if (!enif_inspect_binary(env, argv[0], &data_bin)
@@ -1269,10 +1280,7 @@ static void msgenv_dtor(ErlNifEnv* env, void* obj)
static ERL_NIF_TERM clear_msgenv(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
- union {
- void* vp;
- struct make_term_info* p;
- }mti;
+ mti_t mti;
if (!enif_get_resource(env, argv[0], msgenv_resource_type, &mti.vp)) {
return enif_make_badarg(env);
}
@@ -1285,7 +1293,7 @@ static ERL_NIF_TERM clear_msgenv(ErlNifEnv* env, int argc, const ERL_NIF_TERM ar
static ERL_NIF_TERM grow_blob(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
- union { void* vp; struct make_term_info* p; }mti;
+ mti_t mti;
ERL_NIF_TERM term;
if (!enif_get_resource(env, argv[0], msgenv_resource_type, &mti.vp)
|| (argc>2 && !enif_get_uint(env,argv[2], &mti.p->n))) {
@@ -1301,7 +1309,7 @@ static ERL_NIF_TERM grow_blob(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[
static ERL_NIF_TERM send_blob(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
- union { void* vp; struct make_term_info* p; }mti;
+ mti_t mti;
ErlNifPid to;
ERL_NIF_TERM copy;
int res;
@@ -1316,7 +1324,7 @@ static ERL_NIF_TERM send_blob(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[
static ERL_NIF_TERM send3_blob(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
- union { void* vp; struct make_term_info* p; }mti;
+ mti_t mti;
ErlNifPid to;
ERL_NIF_TERM copy;
int res;
@@ -1334,7 +1342,7 @@ static ERL_NIF_TERM send3_blob(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv
void* threaded_sender(void *arg)
{
- union { void* vp; struct make_term_info* p; }mti;
+ mti_t mti;
mti.vp = arg;
enif_mutex_lock(mti.p->mtx);
@@ -1349,7 +1357,7 @@ void* threaded_sender(void *arg)
static ERL_NIF_TERM send_blob_thread(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
- union { void* vp; struct make_term_info* p; }mti;
+ mti_t mti;
ERL_NIF_TERM copy;
if (!enif_get_resource(env, argv[0], msgenv_resource_type, &mti.vp)
|| !enif_get_local_pid(env,argv[1], &mti.p->to_pid)) {
@@ -1375,7 +1383,7 @@ static ERL_NIF_TERM send_blob_thread(ErlNifEnv* env, int argc, const ERL_NIF_TER
static ERL_NIF_TERM join_send_thread(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
- union { void* vp; struct make_term_info* p; }mti;
+ mti_t mti;
int err;
if (!enif_get_resource(env, argv[0], msgenv_resource_type, &mti.vp)) {
return enif_make_badarg(env);
@@ -1392,7 +1400,7 @@ static ERL_NIF_TERM join_send_thread(ErlNifEnv* env, int argc, const ERL_NIF_TER
static ERL_NIF_TERM copy_blob(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
- union { void* vp; struct make_term_info* p; }mti;
+ mti_t mti;
if (!enif_get_resource(env, argv[0], msgenv_resource_type, &mti.vp)) {
return enif_make_badarg(env);
}
diff --git a/erts/epmd/src/epmd.c b/erts/epmd/src/epmd.c
index 08576d923f..2267f9b12b 100644
--- a/erts/epmd/src/epmd.c
+++ b/erts/epmd/src/epmd.c
@@ -324,7 +324,11 @@ static void run_daemon(EpmdVars *g)
}
/* move cwd to root to make sure we are not on a mounted filesystem */
- chdir("/");
+ if (chdir("/") < 0)
+ {
+ dbg_perror(g,"epmd: chdir() failed");
+ epmd_cleanup_exit(g,1);
+ }
umask(0);
diff --git a/erts/epmd/src/epmd_cli.c b/erts/epmd/src/epmd_cli.c
index ac55ba6bb6..2377c0dfe7 100644
--- a/erts/epmd/src/epmd_cli.c
+++ b/erts/epmd/src/epmd_cli.c
@@ -104,7 +104,10 @@ void epmd_call(EpmdVars *g,int what)
fd = conn_to_epmd(g);
put_int16(1,buf);
buf[2] = what;
- write(fd,buf,3);
+ if (write(fd, buf, 3) != 3) {
+ printf("epmd: Can't write to epmd\n");
+ epmd_cleanup_exit(g,1);
+ }
if (read(fd,(char *)&i,4) != 4) {
if (!g->silent)
printf("epmd: no response from local epmd\n");
diff --git a/erts/epmd/src/epmd_srv.c b/erts/epmd/src/epmd_srv.c
index 5debae26b6..da575affa1 100644
--- a/erts/epmd/src/epmd_srv.c
+++ b/erts/epmd/src/epmd_srv.c
@@ -102,7 +102,8 @@ void run(EpmdVars *g)
dbg_printf(g,2,"try to initiate listening port %d", g->port);
- if (g->addresses != NULL)
+ if (g->addresses != NULL && /* String contains non-separator characters if: */
+ g->addresses[strspn(g->addresses," ,")] != '\000')
{
char *tmp;
char *token;
diff --git a/erts/etc/win32/erlsrv/erlsrv_interactive.c b/erts/etc/win32/erlsrv/erlsrv_interactive.c
index 13e029b364..4c990a694d 100644
--- a/erts/etc/win32/erlsrv/erlsrv_interactive.c
+++ b/erts/etc/win32/erlsrv/erlsrv_interactive.c
@@ -135,7 +135,12 @@ void print_last_error(void){
fprintf(stderr,"Error: %s",mes);
LocalFree(mes);
}
-
+
+static int get_last_error(void)
+{
+ return (last_error) ? last_error : GetLastError();
+}
+
static BOOL install_service(void){
SC_HANDLE scm;
SC_HANDLE service;
@@ -508,7 +513,7 @@ int do_usage(char *arg0){
"\t[{-sn[ame] | -n[ame]} [<nodename>]]\n"
"\t[-d[ebugtype] [{new|reuse|console}]]\n"
"\t[-ar[gs] [<limited erl arguments>]]\n\n"
- "%s {start | stop | disable | enable} <servicename>\n\n"
+ "%s {start | start_disabled | stop | disable | enable} <servicename>\n\n"
"%s remove <servicename>\n\n"
"%s rename <servicename> <servicename>\n\n"
"%s list [<servicename>]\n\n"
@@ -561,6 +566,45 @@ int do_manage(int argc,char **argv){
return 0;
}
}
+ if(!_stricmp(action,"start_disabled")){
+ if(!enable_service()){
+ fprintf(stderr,"%s: Failed to enable service %s.\n",
+ argv[0],service_name);
+ print_last_error();
+ return 1;
+ }
+ if(!start_service() && get_last_error() != ERROR_SERVICE_ALREADY_RUNNING){
+ fprintf(stderr,"%s: Failed to start service %s.\n",
+ argv[0],service_name);
+ print_last_error();
+ goto failure_starting;
+ }
+
+ if(!wait_service_trans(SERVICE_STOPPED, SERVICE_START_PENDING,
+ SERVICE_RUNNING, 60)){
+ fprintf(stderr,"%s: Failed to start service %s.\n",
+ argv[0],service_name);
+ print_last_error();
+ goto failure_starting;
+ }
+
+ if(!disable_service()){
+ fprintf(stderr,"%s: Failed to disable service %s.\n",
+ argv[0],service_name);
+ print_last_error();
+ return 1;
+ }
+ printf("%s: Service %s started.\n",
+ argv[0],service_name);
+ return 0;
+ failure_starting:
+ if(!disable_service()){
+ fprintf(stderr,"%s: Failed to disable service %s.\n",
+ argv[0],service_name);
+ print_last_error();
+ }
+ return 1;
+ }
if(!_stricmp(action,"stop")){
if(!stop_service()){
fprintf(stderr,"%s: Failed to stop service %s.\n",
@@ -841,6 +885,7 @@ int do_add_or_set(int argc, char **argv){
argv[0], service_name);
return 0;
}
+
int do_rename(int argc, char **argv){
RegEntry *current = empty_reg_tab();
RegEntry *dummy = empty_reg_tab();
@@ -1129,35 +1174,131 @@ void read_arguments(int *pargc, char ***pargv){
*pargc = argc;
*pargv = argv;
}
+
+/* Create a free-for-all ACL to set on the semaphore */
+PACL get_acl(PSECURITY_DESCRIPTOR secdescp)
+{
+ DWORD acl_length = 0;
+ PSID auth_users_sidp = NULL;
+ PACL aclp = NULL;
+ SID_IDENTIFIER_AUTHORITY ntauth = SECURITY_NT_AUTHORITY;
+
+ if(!InitializeSecurityDescriptor(secdescp, SECURITY_DESCRIPTOR_REVISION)) {
+ return NULL;
+ }
+
+ if(!AllocateAndInitializeSid(&ntauth,
+ 1,
+ SECURITY_AUTHENTICATED_USER_RID,
+ 0, 0, 0, 0, 0, 0, 0,
+ &auth_users_sidp)) {
+ return NULL;
+ }
+
+ acl_length = sizeof(ACL) +
+ sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) +
+ GetLengthSid(auth_users_sidp);
+
+ if((aclp = (PACL) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, acl_length)) == NULL) {
+ FreeSid(auth_users_sidp);
+ return NULL;
+ }
+
+ if(!InitializeAcl(aclp, acl_length, ACL_REVISION)) {
+ FreeSid(auth_users_sidp);
+ HeapFree(GetProcessHeap(), 0, aclp);
+ return NULL;
+ }
+
+ if(!AddAccessAllowedAce(aclp, ACL_REVISION, SEMAPHORE_ALL_ACCESS, auth_users_sidp)) {
+ FreeSid(auth_users_sidp);
+ HeapFree(GetProcessHeap(), 0, aclp);
+ return NULL;
+ }
+
+ if(!SetSecurityDescriptorDacl(secdescp, TRUE, aclp, FALSE)) {
+ FreeSid(auth_users_sidp);
+ HeapFree(GetProcessHeap(), 0, aclp);
+ return NULL;
+ }
+ return aclp;
+}
+
+static HANDLE lock_semaphore = NULL;
+
+int take_lock(void) {
+ SECURITY_ATTRIBUTES attr;
+ PACL aclp;
+ SECURITY_DESCRIPTOR secdesc;
+
+ if ((aclp = get_acl(&secdesc)) == NULL) {
+ return -1;
+ }
+
+ memset(&attr,0,sizeof(attr));
+ attr.nLength = sizeof(attr);
+ attr.lpSecurityDescriptor = &secdesc;
+ attr.bInheritHandle = FALSE;
+
+ if ((lock_semaphore = CreateSemaphore(&attr, 1, 1, ERLSRV_INTERACTIVE_GLOBAL_SEMAPHORE)) == NULL) {
+ return -1;
+ }
+
+ if (WaitForSingleObject(lock_semaphore,INFINITE) != WAIT_OBJECT_0) {
+ return -1;
+ }
+
+ HeapFree(GetProcessHeap(), 0, aclp);
+ return 0;
+}
+
+void release_lock(void) {
+ ReleaseSemaphore(lock_semaphore,1,NULL);
+}
+
int interactive_main(int argc, char **argv){
char *action = argv[1];
-
+ int res;
+
+ if (take_lock() != 0) {
+ fprintf(stderr,"%s: unable to acquire global lock (%s).\n",argv[0],
+ ERLSRV_INTERACTIVE_GLOBAL_SEMAPHORE);
+ return 1;
+ }
+
if(!_stricmp(action,"readargs")){
- read_arguments(&argc,&argv);
- action = argv[1];
+ read_arguments(&argc,&argv);
+ action = argv[1];
}
if(!_stricmp(action,"set") || !_stricmp(action,"add"))
- return do_add_or_set(argc,argv);
- if(!_stricmp(action,"rename"))
- return do_rename(argc,argv);
- if(!_stricmp(action,"remove"))
- return do_remove(argc,argv);
- if(!_stricmp(action,"list"))
- return do_list(argc,argv);
- if(!_stricmp(action,"start") ||
- !_stricmp(action,"stop") ||
- !_stricmp(action,"enable") ||
- !_stricmp(action,"disable"))
- return do_manage(argc,argv);
- if(_stricmp(action,"?") &&
- _stricmp(action,"/?") &&
- _stricmp(action,"-?") &&
- *action != 'h' &&
- *action != 'H')
+ res = do_add_or_set(argc,argv);
+ else if(!_stricmp(action,"rename"))
+ res = do_rename(argc,argv);
+ else if(!_stricmp(action,"remove"))
+ res = do_remove(argc,argv);
+ else if(!_stricmp(action,"list"))
+ res = do_list(argc,argv);
+ else if(!_stricmp(action,"start") ||
+ !_stricmp(action,"start_disabled") ||
+ !_stricmp(action,"stop") ||
+ !_stricmp(action,"enable") ||
+ !_stricmp(action,"disable"))
+ res = do_manage(argc,argv);
+ else if(_stricmp(action,"?") &&
+ _stricmp(action,"/?") &&
+ _stricmp(action,"-?") &&
+ *action != 'h' &&
+ *action != 'H') {
fprintf(stderr,"%s: action %s not implemented.\n",argv[0],action);
- do_usage(argv[0]);
- return 1;
+ do_usage(argv[0]);
+ res = 1;
+ } else {
+ do_usage(argv[0]);
+ res = 0;
+ }
+ release_lock();
+ return res;
}
diff --git a/erts/etc/win32/erlsrv/erlsrv_interactive.h b/erts/etc/win32/erlsrv/erlsrv_interactive.h
index deacf81899..602da24575 100644
--- a/erts/etc/win32/erlsrv/erlsrv_interactive.h
+++ b/erts/etc/win32/erlsrv/erlsrv_interactive.h
@@ -19,6 +19,8 @@
#ifndef _ERLSRV_INTERACTIVE_H
#define _ERLSRV_INTERACTIVE_H
+#define ERLSRV_INTERACTIVE_GLOBAL_SEMAPHORE "{468d6954-e355-415f-968f-d257cb0feef4}"
+
int interactive_main(int argc, char **argv);
#endif /* _ERLSRV_INTERACTIVE_H */
diff --git a/erts/etc/win32/start_erl.c b/erts/etc/win32/start_erl.c
index dcf8c8b281..6ca7dd9b99 100644
--- a/erts/etc/win32/start_erl.c
+++ b/erts/etc/win32/start_erl.c
@@ -44,6 +44,8 @@ char *progname;
#endif
#define RELEASE_SUBDIR "\\releases"
+#define ERTS_SUBDIR_PREFIX "\\erts-"
+#define BIN_SUBDIR "\\bin"
#define REGISTRY_BASE "Software\\Ericsson\\Erlang\\"
#define DEFAULT_DATAFILE "start_erl.data"
@@ -101,7 +103,8 @@ void exit_help(char *err)
printf("Usage:\n%s\n"
" [<erlang options>] ++\n"
" [-data <datafile>]\n"
- " [-reldir <releasedir>]\n"
+ " {-rootdir <erlang root directory> | \n"
+ " -reldir <releasedir>}\n"
" [-bootflags <bootflagsfile>]\n"
" [-noconfig]\n", progname);
@@ -177,8 +180,9 @@ void split_commandline(void)
*/
char * unquote_optionarg(char *str, char **strp)
{
- char *newstr = (char *)malloc(strlen(str)+1); /* This one is realloc:ed later */
- int i=0, inquote=0;
+ char *newstr = (char *)malloc(strlen(str)+1); /* This one is
+ realloc:ed later */
+ int i = 0, inquote = 0;
assert(newstr);
assert(str);
@@ -223,8 +227,8 @@ char * unquote_optionarg(char *str, char **strp)
/*
- * Parses MyCommandLine and tries to fill in all the required option variables
- * (one way or another).
+ * Parses MyCommandLine and tries to fill in all the required option
+ * variables (in one way or another).
*/
void parse_commandline(void)
{
@@ -237,6 +241,11 @@ void parse_commandline(void)
*cmdline++;
if( strnicmp(cmdline, "data", 4) == 0) {
DataFileName = unquote_optionarg(cmdline+4, &cmdline);
+ } else if( strnicmp(cmdline, "rootdir", 7) == 0) {
+ RootDir = unquote_optionarg(cmdline+7, &cmdline);
+#ifdef _DEBUG
+ fprintf(stderr, "RootDir: '%s'\n", RootDir);
+#endif
} else if( strnicmp(cmdline, "reldir", 6) == 0) {
RelDir = unquote_optionarg(cmdline+6, &cmdline);
#ifdef _DEBUG
@@ -266,8 +275,8 @@ void parse_commandline(void)
* Read the data file specified and get the version and release number
* from it.
*
- * This function also construct the correct RegistryKey from the version information
- * retrieved.
+ * This function also construct the correct RegistryKey from the version
+ * information retrieved.
*/
void read_datafile(void)
{
@@ -325,88 +334,6 @@ void read_datafile(void)
/*
- * Read the registry keys we need
- */
-void read_registry_keys(void)
-{
- HKEY hReg;
- ULONG lLen;
-
- /* Create the RegistryKey name */
- RegistryKey = (char *) malloc(strlen(REGISTRY_BASE) +
- strlen(Version) + 1);
- assert(RegistryKey);
- sprintf(RegistryKey, REGISTRY_BASE "%s", Version);
-
- /* We always need to find BinDir */
- if( (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
- RegistryKey,
- 0,
- KEY_READ,
- &hReg)) != ERROR_SUCCESS ) {
- exit_help("Could not open registry key.");
- }
-
- /* First query size of data */
- if( (RegQueryValueEx(hReg,
- "Bindir",
- NULL,
- NULL,
- NULL,
- &lLen)) != ERROR_SUCCESS) {
- exit_help("Failed to query BinDir of release.\n");
- }
-
- /* Allocate enough space */
- BinDir = (char *)malloc(lLen+1);
- assert(BinDir);
- /* Retrieve the value */
- if( (RegQueryValueEx(hReg,
- "Bindir",
- NULL,
- NULL,
- (unsigned char *) BinDir,
- &lLen)) != ERROR_SUCCESS) {
- exit_help("Failed to query BinDir of release (2).\n");
- }
-
-#ifdef _DEBUG
- fprintf(stderr, "Bindir: '%s'\n", BinDir);
-#endif
-
- /* We also need the rootdir, in case we need to build RelDir later */
-
- /* First query size of data */
- if( (RegQueryValueEx(hReg,
- "Rootdir",
- NULL,
- NULL,
- NULL,
- &lLen)) != ERROR_SUCCESS) {
- exit_help("Failed to query RootDir of release.\n");
- }
-
- /* Allocate enough space */
- RootDir = (char *) malloc(lLen+1);
- assert(RootDir);
- /* Retrieve the value */
- if( (RegQueryValueEx(hReg,
- "Rootdir",
- NULL,
- NULL,
- (unsigned char *) RootDir,
- &lLen)) != ERROR_SUCCESS) {
- exit_help("Failed to query RootDir of release (2).\n");
- }
-
-#ifdef _DEBUG
- fprintf(stderr, "Rootdir: '%s'\n", RootDir);
-#endif
-
- RegCloseKey(hReg);
-}
-
-/*
* Read the bootflags. This file contains extra command line options to erl.exe
*/
void read_bootflags(void)
@@ -424,7 +351,8 @@ void read_bootflags(void)
exit_help("Need -reldir when -bootflags "
"filename has relative path.");
} else {
- newname = (char *)malloc(strlen(BootFlagsFile)+strlen(RelDir)+strlen(Release)+3);
+ newname = (char *)malloc(strlen(BootFlagsFile)+
+ strlen(RelDir)+strlen(Release)+3);
assert(newname);
sprintf(newname, "%s\\%s\\%s", RelDir, Release, BootFlagsFile);
free(BootFlagsFile);
@@ -436,8 +364,6 @@ void read_bootflags(void)
fprintf(stderr, "BootFlagsFile: '%s'\n", BootFlagsFile);
#endif
-
-
if( (fp=fopen(BootFlagsFile, "rb")) == NULL) {
exit_help("Could not open BootFlags file.");
}
@@ -605,32 +531,49 @@ void complete_options(void)
sz = nsz;
}
if (RelDir == NULL) {
- if(DataFileName){
- /* Needs to be absolute for this to work, but we
- can try... */
- read_datafile();
- read_registry_keys();
- } else {
- /* Impossible to find all data... */
- exit_help("Need either Release directory or an absolute "
- "datafile name.");
- }
- /* Ok, construct our own RelDir from RootDir */
- RelDir = (char *) malloc(strlen(RootDir)+strlen(RELEASE_SUBDIR)+1);
- assert(RelDir);
- sprintf(RelDir, "%s" RELEASE_SUBDIR, RootDir);
+ if (!RootDir) {
+ /* Impossible to find all data... */
+ exit_help("Need either Root directory nor Release directory.");
+ }
+ /* Ok, construct our own RelDir from RootDir */
+ RelDir = (char *) malloc(strlen(RootDir)+strlen(RELEASE_SUBDIR)+1);
+ assert(RelDir);
+ sprintf(RelDir, "%s" RELEASE_SUBDIR, RootDir);
+ read_datafile();
} else {
read_datafile();
- read_registry_keys();
}
} else {
read_datafile();
- read_registry_keys();
}
+ if( !RootDir ) {
+ /* Try to construct RootDir from RelDir */
+ char *p;
+ RootDir = malloc(strlen(RelDir)+1);
+ strcpy(RootDir,RelDir);
+ p = RootDir+strlen(RootDir)-1;
+ if (p >= RootDir && (*p == '/' || *p == '\\'))
+ --p;
+ while (p >= RootDir && *p != '/' && *p != '\\')
+ --p;
+ if (p <= RootDir) { /* Empty RootDir is also an error */
+ exit_help("Cannot determine Root directory from "
+ "Release directory.");
+ }
+ *p = '\0';
+ }
+
+
+ BinDir = (char *) malloc(strlen(RootDir)+strlen(ERTS_SUBDIR_PREFIX)+
+ strlen(Version)+strlen(BIN_SUBDIR)+1);
+ assert(BinDir);
+ sprintf(BinDir, "%s" ERTS_SUBDIR_PREFIX "%s" BIN_SUBDIR, RootDir, Version);
+
read_bootflags();
#ifdef _DEBUG
fprintf(stderr, "RelDir: '%s'\n", RelDir);
+ fprintf(stderr, "BinDir: '%s'\n", BinDir);
#endif
}
diff --git a/erts/example/matrix_nif.c b/erts/example/matrix_nif.c
index c5e01dade5..43f9526ae3 100644
--- a/erts/example/matrix_nif.c
+++ b/erts/example/matrix_nif.c
@@ -31,7 +31,19 @@ typedef struct
unsigned nrows;
unsigned ncols;
double* data;
-}Matrix;
+} Matrix;
+
+/*
+ * Use a union for pointer type conversion to avoid compiler warnings
+ * about strict-aliasing violations with gcc-4.1. gcc >= 4.2 does not
+ * emit the warning.
+ * TODO: Reconsider use of union once gcc-4.1 is obsolete?
+ */
+typedef union
+{
+ void* vp;
+ Matrix* p;
+} mx_t;
#define POS(MX, ROW, COL) ((MX)->data[(ROW)* (MX)->ncols + (COL)])
@@ -44,8 +56,9 @@ static ErlNifResourceType* resource_type = NULL;
static int load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info)
{
- ErlNifResourceType* rt = enif_open_resource_type(env, "matrix_nif_example",
- matrix_dtor,
+ ErlNifResourceType* rt = enif_open_resource_type(env, NULL,
+ "matrix_nif_example",
+ matrix_dtor,
ERL_NIF_RT_CREATE, NULL);
if (rt == NULL) {
return -1;
@@ -90,12 +103,12 @@ static ERL_NIF_TERM create(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
}
ret = enif_make_resource(env, mx);
- enif_release_resource(env, mx);
+ enif_release_resource(mx);
return ret;
badarg:
if (mx != NULL) {
- enif_release_resource(env,mx);
+ enif_release_resource(mx);
}
return enif_make_badarg(env);
}
@@ -104,14 +117,14 @@ badarg:
static ERL_NIF_TERM pos(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
/* pos(Matrix, Row, Column) -> float() */
- Matrix* mx;
+ mx_t mx;
unsigned i, j;
- if (!enif_get_resource(env, argv[0], resource_type, (void**)&mx) ||
- !enif_get_uint(env, argv[1], &i) || (--i >= mx->nrows) ||
- !enif_get_uint(env, argv[2], &j) || (--j >= mx->ncols)) {
+ if (!enif_get_resource(env, argv[0], resource_type, &mx.vp) ||
+ !enif_get_uint(env, argv[1], &i) || (--i >= mx.p->nrows) ||
+ !enif_get_uint(env, argv[2], &j) || (--j >= mx.p->ncols)) {
return enif_make_badarg(env);
}
- return enif_make_double(env, POS(mx, i,j));
+ return enif_make_double(env, POS(mx.p, i,j));
}
static ERL_NIF_TERM add(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
@@ -119,37 +132,38 @@ static ERL_NIF_TERM add(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
/* add(Matrix_A, Matrix_B) -> Matrix_Sum */
unsigned i, j;
ERL_NIF_TERM ret;
- Matrix* mxA = NULL;
- Matrix* mxB = NULL;
- Matrix* mxS = NULL;
+ mx_t mxA, mxB, mxS;
+ mxA.p = NULL;
+ mxB.p = NULL;
+ mxS.p = NULL;
- if (!enif_get_resource(env, argv[0], resource_type, (void**)&mxA) ||
- !enif_get_resource(env, argv[1], resource_type, (void**)&mxB) ||
- mxA->nrows != mxB->nrows ||
- mxB->ncols != mxB->ncols) {
+ if (!enif_get_resource(env, argv[0], resource_type, &mxA.vp) ||
+ !enif_get_resource(env, argv[1], resource_type, &mxB.vp) ||
+ mxA.p->nrows != mxB.p->nrows ||
+ mxB.p->ncols != mxB.p->ncols) {
return enif_make_badarg(env);
}
- mxS = alloc_matrix(env, mxA->nrows, mxA->ncols);
- for (i = 0; i < mxA->nrows; i++) {
- for (j = 0; j < mxA->ncols; j++) {
- POS(mxS, i, j) = POS(mxA, i, j) + POS(mxB, i, j);
+ mxS.p = alloc_matrix(env, mxA.p->nrows, mxA.p->ncols);
+ for (i = 0; i < mxA.p->nrows; i++) {
+ for (j = 0; j < mxA.p->ncols; j++) {
+ POS(mxS.p, i, j) = POS(mxA.p, i, j) + POS(mxB.p, i, j);
}
}
- ret = enif_make_resource(env, mxS);
- enif_release_resource(env, mxS);
+ ret = enif_make_resource(env, mxS.p);
+ enif_release_resource(mxS.p);
return ret;
}
static ERL_NIF_TERM size_of(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
/* size(Matrix) -> {Nrows, Ncols} */
- Matrix* mx;
- if (!enif_get_resource(env, argv[0], resource_type, (void**)&mx)) {
+ mx_t mx;
+ if (!enif_get_resource(env, argv[0], resource_type, &mx.vp)) {
return enif_make_badarg(env);
}
- return enif_make_tuple2(env, enif_make_uint(env, mx->nrows),
- enif_make_uint(env, mx->ncols));
+ return enif_make_tuple2(env, enif_make_uint(env, mx.p->nrows),
+ enif_make_uint(env, mx.p->ncols));
}
static ERL_NIF_TERM to_term(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
@@ -157,16 +171,17 @@ static ERL_NIF_TERM to_term(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
/* to_term(Matrix) -> [[first row], [second row], ...,[last row]] */
unsigned i, j;
ERL_NIF_TERM res;
- Matrix* mx = NULL;
+ mx_t mx;
+ mx.p = NULL;
- if (!enif_get_resource(env, argv[0], resource_type, (void**)&mx)) {
+ if (!enif_get_resource(env, argv[0], resource_type, &mx.vp)) {
return enif_make_badarg(env);
}
res = enif_make_list(env, 0);
- for (i = mx->nrows; i-- > 0; ) {
+ for (i = mx.p->nrows; i-- > 0; ) {
ERL_NIF_TERM row = enif_make_list(env, 0);
- for (j = mx->ncols; j-- > 0; ) {
- row = enif_make_list_cell(env, enif_make_double(env, POS(mx,i,j)),
+ for (j = mx.p->ncols; j-- > 0; ) {
+ row = enif_make_list_cell(env, enif_make_double(env, POS(mx.p,i,j)),
row);
}
res = enif_make_list_cell(env, row, res);
@@ -183,17 +198,17 @@ static int get_number(ErlNifEnv* env, ERL_NIF_TERM term, double* dp)
static Matrix* alloc_matrix(ErlNifEnv* env, unsigned nrows, unsigned ncols)
{
- Matrix* mx = enif_alloc_resource(env, resource_type, sizeof(Matrix));
+ Matrix* mx = enif_alloc_resource(resource_type, sizeof(Matrix));
mx->nrows = nrows;
mx->ncols = ncols;
- mx->data = enif_alloc(env, nrows*ncols*sizeof(double));
+ mx->data = enif_alloc(nrows*ncols*sizeof(double));
return mx;
}
static void matrix_dtor(ErlNifEnv* env, void* obj)
{
Matrix* mx = (Matrix*) obj;
- enif_free(env, mx->data);
+ enif_free(mx->data);
mx->data = NULL;
}
diff --git a/erts/include/internal/ethread_header_config.h.in b/erts/include/internal/ethread_header_config.h.in
index f394d790d2..1fb630cb78 100644
--- a/erts/include/internal/ethread_header_config.h.in
+++ b/erts/include/internal/ethread_header_config.h.in
@@ -90,7 +90,7 @@
/* Define if sched_yield() returns an int. */
#undef ETHR_SCHED_YIELD_RET_INT
-/* Define if you want compatibilty with x86 processors before pentium4. */
+/* Define if you want compatibility with x86 processors before pentium4. */
#undef ETHR_PRE_PENTIUM4_COMPAT
/* Define if you have the pthread_rwlockattr_setkind_np() function. */
diff --git a/erts/lib_src/common/erl_misc_utils.c b/erts/lib_src/common/erl_misc_utils.c
index 35b148990a..5e94ff19db 100644
--- a/erts/lib_src/common/erl_misc_utils.c
+++ b/erts/lib_src/common/erl_misc_utils.c
@@ -55,6 +55,12 @@
# ifdef HAVE_UNISTD_H
# include <unistd.h>
# endif
+# if defined(_SC_NPROC_CONF) && !defined(_SC_NPROCESSORS_CONF)
+# define _SC_NPROCESSORS_CONF _SC_NPROC_CONF
+# endif
+# if defined(_SC_NPROC_ONLN) && !defined(_SC_NPROCESSORS_ONLN)
+# define _SC_NPROCESSORS_ONLN _SC_NPROC_ONLN
+# endif
# if (defined(NO_SYSCONF) || !defined(_SC_NPROCESSORS_CONF))
# ifdef HAVE_SYS_SYSCTL_H
# include <sys/sysctl.h>
diff --git a/erts/lib_src/common/erl_printf.c b/erts/lib_src/common/erl_printf.c
index 72d18ab6f1..6aa4569d44 100644
--- a/erts/lib_src/common/erl_printf.c
+++ b/erts/lib_src/common/erl_printf.c
@@ -108,7 +108,7 @@ write_f_add_cr(void *vfp, char* buf, size_t len)
if (PUTC(buf[i], (FILE *) vfp) == EOF)
return get_error_result();
}
- return 0;
+ return len;
}
static int
@@ -126,13 +126,14 @@ write_f(void *vfp, char* buf, size_t len)
#endif
if (FWRITE((void *) buf, sizeof(char), len, (FILE *) vfp) != len)
return get_error_result();
- return 0;
+ return len;
}
static int
write_fd(void *vfdp, char* buf, size_t len)
{
ssize_t size;
+ size_t res = len;
ASSERT(vfdp);
while (len) {
@@ -149,7 +150,7 @@ write_fd(void *vfdp, char* buf, size_t len)
len -= size;
}
- return 0;
+ return res;
}
static int
@@ -160,7 +161,7 @@ write_s(void *vwbufpp, char* bufp, size_t len)
ASSERT(len > 0);
memcpy((void *) *wbufpp, (void *) bufp, len);
*wbufpp += len;
- return 0;
+ return len;
}
@@ -182,6 +183,7 @@ write_sn(void *vwsnap, char* buf, size_t len)
memcpy((void *) wsnap->buf, (void *) buf, sz);
wsnap->buf += sz;
wsnap->len -= sz;
+ return sz;
}
return 0;
}
@@ -201,7 +203,7 @@ write_ds(void *vdsbufp, char* buf, size_t len)
}
memcpy((void *) (dsbufp->str + dsbufp->str_len), (void *) buf, len);
dsbufp->str_len += len;
- return 0;
+ return len;
}
int
diff --git a/erts/preloaded/ebin/zlib.beam b/erts/preloaded/ebin/zlib.beam
index d400269ed0..cda53f7692 100644
--- a/erts/preloaded/ebin/zlib.beam
+++ b/erts/preloaded/ebin/zlib.beam
Binary files differ
diff --git a/erts/preloaded/src/erl_prim_loader.erl b/erts/preloaded/src/erl_prim_loader.erl
index ccfa7978c8..4a72bae105 100644
--- a/erts/preloaded/src/erl_prim_loader.erl
+++ b/erts/preloaded/src/erl_prim_loader.erl
@@ -396,7 +396,7 @@ handle_timeout(State = #state{loader = inet}, Parent) ->
inet_timeout_handler(State, Parent).
%%% --------------------------------------------------------
-%%% Functions which handles efile as prim_loader (default).
+%%% Functions which handle efile as prim_loader (default).
%%% --------------------------------------------------------
%%% Reading many files in parallel is an optimization.
@@ -523,7 +523,7 @@ efile_timeout_handler(#state{n_timeouts = N} = State, _Parent) ->
end.
%%% --------------------------------------------------------
-%%% Functions which handles inet prim_loader
+%%% Functions which handle inet prim_loader
%%% --------------------------------------------------------
%%
diff --git a/erts/preloaded/src/init.erl b/erts/preloaded/src/init.erl
index e52c813029..c9c434dea0 100644
--- a/erts/preloaded/src/init.erl
+++ b/erts/preloaded/src/init.erl
@@ -345,7 +345,7 @@ notify(Pids) ->
lists:foreach(fun(Pid) -> Pid ! {init,started} end, Pids).
%% Garbage collect all info about initially loaded modules.
-%% This information is temporary stored until the code_server
+%% This information is temporarily stored until the code_server
%% is started.
%% We force the garbage collection as the init process holds
%% this information during the initialisation of the system and
diff --git a/erts/preloaded/src/prim_file.erl b/erts/preloaded/src/prim_file.erl
index ac7570582e..fd2d4a1530 100644
--- a/erts/preloaded/src/prim_file.erl
+++ b/erts/preloaded/src/prim_file.erl
@@ -374,7 +374,7 @@ read(#file_descriptor{module = ?MODULE, data = {Port, _}}, Size)
{ok, Data};
{error, enomem} ->
%% Garbage collecting here might help if
- %% the current processes has some old binaries left.
+ %% the current processes have some old binaries left.
erlang:garbage_collect(),
case drv_command(Port, <<?FILE_READ, Size:64>>) of
{ok, {0, _Data}} when Size =/= 0 ->
@@ -824,7 +824,7 @@ list_dir_int(Port, Dir) ->
%% Opens a driver port and converts any problems into {error, emfile}.
-%% Returns {ok, Port} when succesful.
+%% Returns {ok, Port} when successful.
drv_open(Driver, Portopts) ->
try erlang:open_port({spawn, Driver}, Portopts) of
@@ -940,7 +940,7 @@ drv_get_response(Port) ->
-%% Converts a list of mode atoms into an mode word for the driver.
+%% Converts a list of mode atoms into a mode word for the driver.
%% Returns {Mode, Portopts, Setopts} where Portopts is a list of
%% options for erlang:open_port/2 and Setopts is a list of
%% setopt commands to send to the port, or error Reason upon failure.
diff --git a/erts/preloaded/src/prim_zip.erl b/erts/preloaded/src/prim_zip.erl
index 6a9856fdad..5dc8e3ca13 100644
--- a/erts/preloaded/src/prim_zip.erl
+++ b/erts/preloaded/src/prim_zip.erl
@@ -21,7 +21,7 @@
-module(prim_zip).
-%% unzipping piecemal
+%% unzipping piecemeal
-export([
open/1,
open/3,
diff --git a/erts/preloaded/src/zlib.erl b/erts/preloaded/src/zlib.erl
index 6cc7b27114..210532edac 100644
--- a/erts/preloaded/src/zlib.erl
+++ b/erts/preloaded/src/zlib.erl
@@ -173,7 +173,7 @@ deflateInit(Z, Level, Method, WindowBits, MemLevel, Strategy) ->
-spec deflateSetDictionary(Z, Dictionary) -> Adler32 when
Z :: zstream(),
- Dictionary :: binary(),
+ Dictionary :: iodata(),
Adler32 :: integer().
deflateSetDictionary(Z, Dictionary) ->
call(Z, ?DEFLATE_SETDICT, Dictionary).
@@ -232,7 +232,7 @@ inflateInit(Z, WindowBits) ->
-spec inflateSetDictionary(Z, Dictionary) -> 'ok' when
Z :: zstream(),
- Dictionary :: binary().
+ Dictionary :: iodata().
inflateSetDictionary(Z, Dictionary) ->
call(Z, ?INFLATE_SETDICT, Dictionary).
@@ -283,38 +283,36 @@ getBufSize(Z) ->
crc32(Z) ->
call(Z, ?CRC32_0, []).
--spec crc32(Z, Binary) -> CRC when
+-spec crc32(Z, Data) -> CRC when
Z :: zstream(),
- Binary :: binary(),
+ Data :: iodata(),
CRC :: integer().
-crc32(Z, Binary) ->
- call(Z, ?CRC32_1, Binary).
+crc32(Z, Data) ->
+ call(Z, ?CRC32_1, Data).
--spec crc32(Z, PrevCRC, Binary) -> CRC when
+-spec crc32(Z, PrevCRC, Data) -> CRC when
Z :: zstream(),
PrevCRC :: integer(),
- Binary :: binary(),
+ Data :: iodata(),
CRC :: integer().
-crc32(Z, CRC, Binary) when is_binary(Binary), is_integer(CRC) ->
- call(Z, ?CRC32_2, <<CRC:32, Binary/binary>>);
-crc32(_Z, _CRC, _Binary) ->
- erlang:error(badarg).
+crc32(Z, CRC, Data) ->
+ call(Z, ?CRC32_2, [<<CRC:32>>, Data]).
--spec adler32(Z, Binary) -> CheckSum when
+-spec adler32(Z, Data) -> CheckSum when
Z :: zstream(),
- Binary :: binary(),
+ Data :: iodata(),
CheckSum :: integer().
-adler32(Z, Binary) ->
- call(Z, ?ADLER32_1, Binary).
+adler32(Z, Data) ->
+ call(Z, ?ADLER32_1, Data).
--spec adler32(Z, PrevAdler, Binary) -> CheckSum when
+-spec adler32(Z, PrevAdler, Data) -> CheckSum when
Z :: zstream(),
PrevAdler :: integer(),
- Binary :: binary(),
+ Data :: iodata(),
CheckSum :: integer().
-adler32(Z, Adler, Binary) when is_binary(Binary), is_integer(Adler) ->
- call(Z, ?ADLER32_2, <<Adler:32, Binary/binary>>);
-adler32(_Z, _Adler, _Binary) ->
+adler32(Z, Adler, Data) when is_integer(Adler) ->
+ call(Z, ?ADLER32_2, [<<Adler:32>>, Data]);
+adler32(_Z, _Adler, _Data) ->
erlang:error(badarg).
-spec crc32_combine(Z, CRC1, CRC2, Size2) -> CRC when
@@ -346,76 +344,83 @@ getQSize(Z) ->
call(Z, ?GET_QSIZE, []).
%% compress/uncompress zlib with header
--spec compress(Binary) -> Compressed when
- Binary :: binary(),
+-spec compress(Data) -> Compressed when
+ Data :: iodata(),
Compressed :: binary().
-compress(Binary) ->
+compress(Data) ->
Z = open(),
deflateInit(Z, default),
- Bs = deflate(Z, Binary,finish),
+ Bs = deflate(Z, Data, finish),
deflateEnd(Z),
close(Z),
- list_to_binary(Bs).
+ iolist_to_binary(Bs).
--spec uncompress(Binary) -> Decompressed when
- Binary :: binary(),
+-spec uncompress(Data) -> Decompressed when
+ Data :: iodata(),
Decompressed :: binary().
-uncompress(Binary) when byte_size(Binary) >= 8 ->
- Z = open(),
- inflateInit(Z),
- Bs = inflate(Z, Binary),
- inflateEnd(Z),
- close(Z),
- list_to_binary(Bs);
-uncompress(Binary) when is_binary(Binary) -> erlang:error(data_error);
-uncompress(_) -> erlang:error(badarg).
+uncompress(Data) ->
+ try iolist_size(Data) of
+ Size ->
+ if
+ Size >= 8 ->
+ Z = open(),
+ inflateInit(Z),
+ Bs = inflate(Z, Data),
+ inflateEnd(Z),
+ close(Z),
+ iolist_to_binary(Bs);
+ true ->
+ erlang:error(data_error)
+ end
+ catch
+ _:_ ->
+ erlang:error(badarg)
+ end.
%% unzip/zip zlib without header (zip members)
--spec zip(Binary) -> Compressed when
- Binary :: binary(),
+-spec zip(Data) -> Compressed when
+ Data :: iodata(),
Compressed :: binary().
-zip(Binary) ->
+zip(Data) ->
Z = open(),
deflateInit(Z, default, deflated, -?MAX_WBITS, 8, default),
- Bs = deflate(Z, Binary, finish),
+ Bs = deflate(Z, Data, finish),
deflateEnd(Z),
close(Z),
- list_to_binary(Bs).
+ iolist_to_binary(Bs).
--spec unzip(Binary) -> Decompressed when
- Binary :: binary(),
+-spec unzip(Data) -> Decompressed when
+ Data :: iodata(),
Decompressed :: binary().
-unzip(Binary) ->
+unzip(Data) ->
Z = open(),
inflateInit(Z, -?MAX_WBITS),
- Bs = inflate(Z, Binary),
+ Bs = inflate(Z, Data),
inflateEnd(Z),
close(Z),
- list_to_binary(Bs).
+ iolist_to_binary(Bs).
-spec gzip(Data) -> Compressed when
Data :: iodata(),
Compressed :: binary().
-gzip(Data) when is_binary(Data); is_list(Data) ->
+gzip(Data) ->
Z = open(),
deflateInit(Z, default, deflated, 16+?MAX_WBITS, 8, default),
Bs = deflate(Z, Data, finish),
deflateEnd(Z),
close(Z),
- iolist_to_binary(Bs);
-gzip(_) -> erlang:error(badarg).
+ iolist_to_binary(Bs).
--spec gunzip(Binary) -> Decompressed when
- Binary :: binary(),
+-spec gunzip(Data) -> Decompressed when
+ Data :: iodata(),
Decompressed :: binary().
-gunzip(Data) when is_binary(Data); is_list(Data) ->
+gunzip(Data) ->
Z = open(),
inflateInit(Z, 16+?MAX_WBITS),
Bs = inflate(Z, Data),
inflateEnd(Z),
close(Z),
- iolist_to_binary(Bs);
-gunzip(_) -> erlang:error(badarg).
+ iolist_to_binary(Bs).
-spec collect(zstream()) -> iolist().
collect(Z) ->
diff --git a/erts/test/autoimport_SUITE.erl b/erts/test/autoimport_SUITE.erl
index 0e4708e046..71ed5204b1 100644
--- a/erts/test/autoimport_SUITE.erl
+++ b/erts/test/autoimport_SUITE.erl
@@ -87,10 +87,21 @@ autoimports(Config) when is_list(Config) ->
xml(XMLFile) ->
{ok,File} = file:open(XMLFile,[read]),
+ xskip_to_funcs(file:read_line(File),File),
DocData = xloop(file:read_line(File),File),
+ true = DocData =/= [],
file:close(File),
analyze(DocData).
+%% Skip lines up to and including the <funcs> tag.
+xskip_to_funcs({ok,Line},File) ->
+ case re:run(Line,"\\<funcs\\>",[{capture,none}]) of
+ nomatch ->
+ xskip_to_funcs(file:read_line(File),File);
+ match ->
+ ok
+ end.
+
xloop({ok,Line},File) ->
case re:run(Line,"\\<name\\>",[{capture,none}]) of
nomatch ->
diff --git a/erts/test/erlc_SUITE.erl b/erts/test/erlc_SUITE.erl
index 62e0e6813d..a9e28672e3 100644
--- a/erts/test/erlc_SUITE.erl
+++ b/erts/test/erlc_SUITE.erl
@@ -79,7 +79,7 @@ compile_erl(Config) when is_list(Config) ->
?line run(Config, Cmd, FileName, "-Werror",
["compile: warnings being treated as errors\$",
- "Warning: function foo/0 is unused\$",
+ "function foo/0 is unused\$",
"_ERROR_"]),
%% Check a bad file.
@@ -213,13 +213,34 @@ deep_cwd_1(PrivDir) ->
arg_overflow(Config) when is_list(Config) ->
?line {SrcDir, _OutDir, Cmd} = get_cmd(Config),
?line FileName = filename:join(SrcDir, "erl_test_ok.erl"),
- ?line Args = lists:flatten([ ["-D", integer_to_list(N), "=1 "] ||
- N <- lists:seq(1,10000) ]),
+ %% Each -D option will be expanded to three arguments when
+ %% invoking 'erl'.
+ ?line NumDOptions = num_d_options(),
+ ?line Args = lists:flatten([ ["-D", integer_to_list(N, 36), "=1 "] ||
+ N <- lists:seq(1, NumDOptions) ]),
?line run(Config, Cmd, FileName, Args,
["Warning: function foo/0 is unused\$",
"_OK_"]),
ok.
+num_d_options() ->
+ case {os:type(),os:version()} of
+ {{win32,_},_} ->
+ %% The maximum size of a command line in the command
+ %% shell on Windows is 8191 characters.
+ %% Each -D option is expanded to "@dv NN 1", i.e.
+ %% 8 characters. (Numbers up to 1295 can be expressed
+ %% as two 36-base digits.)
+ 1000;
+ {{unix,linux},Version} when Version < {2,6,23} ->
+ %% On some older 64-bit versions of Linux, the maximum number
+ %% of arguments is 16383.
+ %% See: http://www.in-ulm.de/~mascheck/various/argmax/
+ 5440;
+ {_,_} ->
+ 12000
+ end.
+
erlc() ->
case os:find_executable("erlc") of
false ->