diff options
146 files changed, 1415 insertions, 513 deletions
diff --git a/.gitignore b/.gitignore index 79b1d5dfad..0e9d07757f 100644 --- a/.gitignore +++ b/.gitignore @@ -119,7 +119,9 @@ JAVADOC-GENERATED /bootstrap/lib/common_test /bootstrap/lib/edoc /bootstrap/lib/erl_docgen +/bootstrap/lib/erl_interface /bootstrap/lib/hipe +/bootstrap/lib/jinterface /bootstrap/lib/parsetools /bootstrap/lib/runtime_tools /bootstrap/lib/sasl diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c89301d0eb..96db464b52 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -43,6 +43,7 @@ for more information. You can contribute to Erlang/OTP by opening a Pull Request. Make sure you create a new branch for your pull request with `git checkout -b new-branch-name`. +Give the branch a short but descriptive name, like `stdlib/lists-length-fix`. Never do your work directly on `maint` or `master`. ## Fixing a bug @@ -108,6 +109,7 @@ conflicts or include the latest changes. compiled and that it works. * Check for unnecessary whitespace before committing with `git diff --check`. +However, do not fix preexisting whitespace errors in otherwise untouched source lines. Check your coding style: diff --git a/Makefile.in b/Makefile.in index e75bcf7f10..d880bfefa2 100644 --- a/Makefile.in +++ b/Makefile.in @@ -351,6 +351,9 @@ is_cross_configured: target_configured: @echo @TARGET@ +erlang_inst_libdir_configured: + @echo $(ERLANG_INST_LIBDIR) + bootstrap: depend all_bootstraps @@ -681,6 +684,14 @@ tertiary_bootstrap_copy: $(V_at)if test ! -d $(BOOTSTRAP_ROOT)/bootstrap/lib/common_test/include ; then mkdir $(BOOTSTRAP_ROOT)/bootstrap/lib/common_test/include ; fi $(V_at)if test ! -d $(BOOTSTRAP_ROOT)/bootstrap/lib/runtime_tools ; then mkdir $(BOOTSTRAP_ROOT)/bootstrap/lib/runtime_tools ; fi $(V_at)if test ! -d $(BOOTSTRAP_ROOT)/bootstrap/lib/runtime_tools/include ; then mkdir $(BOOTSTRAP_ROOT)/bootstrap/lib/runtime_tools/include ; fi + $(V_at)if test ! -d $(BOOTSTRAP_ROOT)/bootstrap/lib/erl_interface ; then mkdir $(BOOTSTRAP_ROOT)/bootstrap/lib/erl_interface ; fi + $(V_at)if test ! -d $(BOOTSTRAP_ROOT)/bootstrap/lib/erl_interface/include ; then mkdir $(BOOTSTRAP_ROOT)/bootstrap/lib/erl_interface/include ; fi + $(V_at)if test ! -d $(BOOTSTRAP_ROOT)/bootstrap/lib/jinterface/ ; then mkdir $(BOOTSTRAP_ROOT)/bootstrap/lib/jinterface/ ; fi + $(V_at)if test ! -d $(BOOTSTRAP_ROOT)/bootstrap/lib/jinterface/priv ; then mkdir $(BOOTSTRAP_ROOT)/bootstrap/lib/jinterface/priv ; fi + $(V_at)if test ! -d $(BOOTSTRAP_ROOT)/bootstrap/lib/jinterface/priv/com ; then mkdir $(BOOTSTRAP_ROOT)/bootstrap/lib/jinterface/priv/com ; fi + $(V_at)if test ! -d $(BOOTSTRAP_ROOT)/bootstrap/lib/jinterface/priv/com/ericsson ; then mkdir $(BOOTSTRAP_ROOT)/bootstrap/lib/jinterface/priv/com/ericsson ; fi + $(V_at)if test ! -d $(BOOTSTRAP_ROOT)/bootstrap/lib/jinterface/priv/com/ericsson/otp ; then mkdir $(BOOTSTRAP_ROOT)/bootstrap/lib/jinterface/priv/com/ericsson/otp ; fi + $(V_at)if test ! -d $(BOOTSTRAP_ROOT)/bootstrap/lib/jinterface/priv/com/ericsson/otp/erlang ; then mkdir $(BOOTSTRAP_ROOT)/bootstrap/lib/jinterface/priv/com/ericsson/otp/erlang ; fi $(V_at)for x in lib/sasl/ebin/*.beam; do \ BN=`basename $$x`; \ TF=$(BOOTSTRAP_ROOT)/bootstrap/lib/sasl/ebin/$$BN; \ @@ -749,6 +760,38 @@ tertiary_bootstrap_copy: cp $$x $$TF; \ true; \ done +# copy erl_interface includes + $(V_at)for x in lib/erl_interface/include/*; do \ + BN=`basename $$x`; \ + TF=$(BOOTSTRAP_ROOT)/bootstrap/lib/erl_interface/include/$$BN; \ + test -f $$TF && \ + test '!' -z "`find $$x -newer $$TF -print`" && \ + cp $$x $$TF; \ + test '!' -f $$TF && \ + cp $$x $$TF; \ + true; \ + done +# copy jinterface priv directory + $(V_at)for x in lib/jinterface/priv/OtpErlang.jar; do \ + BN=`basename $$x`; \ + TF=$(BOOTSTRAP_ROOT)/bootstrap/lib/jinterface/priv/$$BN; \ + test -f $$TF && \ + test '!' -z "`find $$x -newer $$TF -print`" && \ + cp $$x $$TF; \ + test '!' -f $$TF && \ + cp $$x $$TF; \ + true; \ + done + $(V_at)for x in lib/jinterface/priv/com/ericsson/otp/erlang/*; do \ + BN=`basename $$x`; \ + TF=$(BOOTSTRAP_ROOT)/bootstrap/lib/jinterface/priv/com/ericsson/otp/erlang/$$BN; \ + test -f $$TF && \ + test '!' -z "`find $$x -newer $$TF -print`" && \ + cp $$x $$TF; \ + test '!' -f $$TF && \ + cp $$x $$TF; \ + true; \ + done # $(V_at)cp lib/syntax_tools/ebin/*.beam $(BOOTSTRAP_ROOT)/bootstrap/lib/syntax_tools/ebin doc_bootstrap_build: diff --git a/OTP_VERSION b/OTP_VERSION index 80645cbd62..f222bf6f4c 100644 --- a/OTP_VERSION +++ b/OTP_VERSION @@ -1 +1 @@ -21.0.2 +21.0.4 diff --git a/erts/autoconf/configure.vxworks b/erts/autoconf/configure.vxworks index 5be91319ea..a253848403 100755 --- a/erts/autoconf/configure.vxworks +++ b/erts/autoconf/configure.vxworks @@ -113,6 +113,7 @@ CONFIG_FILES="${ERL_TOP}/erts/emulator/$host/Makefile $erlint_dir/$host/eidefs.mk $epmd_dir/$host/Makefile $internal_tools_dir/make/$host/otp.mk + $internal_tools_dir/make/$host/otp_ded.mk $os_mon_dir/$host/Makefile $zlibdir/$host/Makefile $runtime_tools_dir/$host/Makefile diff --git a/erts/autoconf/vxworks/sed.general b/erts/autoconf/vxworks/sed.general index 96a70e4148..a30eb51169 100644 --- a/erts/autoconf/vxworks/sed.general +++ b/erts/autoconf/vxworks/sed.general @@ -43,6 +43,11 @@ s|@LDFLAGS@|| # FIXME: A bit strange to clear out remaining DED_* s|@DED_LDFLAGS@|| s|@DED_CFLAGS@|| +s|@DED_EMU_THR_DEFS@|| +s|@DED_THR_DEFS@|| +s|@DED_SYS_INCLUDE@|| +s|@WERRORFLAGS@|| +s|@DED_STATIC_CFLAGS@|| s|@STATIC_CFLAGS@|| s|@GCCLIB@|libgcc.a| s|@DEFS@|| diff --git a/erts/autoconf/vxworks/sed.vxworks_cpu32 b/erts/autoconf/vxworks/sed.vxworks_cpu32 index 71663676e7..961adc4104 100644 --- a/erts/autoconf/vxworks/sed.vxworks_cpu32 +++ b/erts/autoconf/vxworks/sed.vxworks_cpu32 @@ -28,6 +28,7 @@ s|@host@|vxworks_cpu32| s|@system_type@|vxworks_cpu32| s|@CC@|@TTPREFIX@cc68k| s|@HCC@|gcc| +s|@GCC@|yes| s|@LD@|@TTPREFIX@ld68k| s|@LIBS@|| s|@DED_LD@|@TTPREFIX@ld68k| diff --git a/erts/autoconf/vxworks/sed.vxworks_ppc32 b/erts/autoconf/vxworks/sed.vxworks_ppc32 index 2146e862fd..1e2e760abc 100644 --- a/erts/autoconf/vxworks/sed.vxworks_ppc32 +++ b/erts/autoconf/vxworks/sed.vxworks_ppc32 @@ -33,6 +33,7 @@ s|@system_type@|vxworks_ppc32| s|@ARCH@|ppc32| s|@CC@|GCC_EXEC_PREFIX=@WIND_BASE@/gnu/3.4.4-vxworks-6.3/@HOST_TYPE@/lib/gcc-lib/ @WIND_BASE@/gnu/3.4.4-vxworks-6.3/@HOST_TYPE@/bin/ccppc -mlongcall| s|@HCC@|gcc| +s|@GCC@|yes| s|@LD@|GCC_EXEC_PREFIX=@WIND_BASE@/gnu/3.4.4-vxworks-6.3/@HOST_TYPE@/lib/gcc-lib/ @WIND_BASE@/gnu/3.4.4-vxworks-6.3/@HOST_TYPE@/bin/ldppc| s|@STRIP@|GCC_EXEC_PREFIX=@WIND_BASE@/gnu/3.4.4-vxworks-6.3/@HOST_TYPE@/lib/gcc-lib/ @WIND_BASE@/workbench-2.3/@HOST_TYPE@/bin/stripppc| s|@SYMPREFIX@|| diff --git a/erts/autoconf/vxworks/sed.vxworks_ppc603 b/erts/autoconf/vxworks/sed.vxworks_ppc603 index fca1ba76d9..5beaae4fc9 100644 --- a/erts/autoconf/vxworks/sed.vxworks_ppc603 +++ b/erts/autoconf/vxworks/sed.vxworks_ppc603 @@ -29,6 +29,7 @@ s|@system_type@|vxworks_ppc603| s|@ARCH@|ppc603| s|@CC@|@TTPREFIX@ccppc -mlongcall| s|@HCC@|gcc| +s|@GCC@|yes| s|@LD@|@TTPREFIX@ldppc| s|@STRIP@|@TTPREFIX@stripppc| s|@SYMPREFIX@|| diff --git a/erts/autoconf/vxworks/sed.vxworks_ppc603_nolongcall b/erts/autoconf/vxworks/sed.vxworks_ppc603_nolongcall index 51c589d79a..2c2f2fa372 100644 --- a/erts/autoconf/vxworks/sed.vxworks_ppc603_nolongcall +++ b/erts/autoconf/vxworks/sed.vxworks_ppc603_nolongcall @@ -29,6 +29,7 @@ s|@system_type@|vxworks_ppc603| s|@ARCH@|ppc603| s|@CC@|@TTPREFIX@ccppc| s|@HCC@|gcc| +s|@GCC@|yes| s|@LD@|@TTPREFIX@ldppc| s|@STRIP@|@TTPREFIX@stripppc| s|@SYMPREFIX@|| diff --git a/erts/autoconf/vxworks/sed.vxworks_ppc860 b/erts/autoconf/vxworks/sed.vxworks_ppc860 index 485504e706..71cf887476 100644 --- a/erts/autoconf/vxworks/sed.vxworks_ppc860 +++ b/erts/autoconf/vxworks/sed.vxworks_ppc860 @@ -29,6 +29,7 @@ s|@system_type@|vxworks_ppc860| s|@ARCH@|ppc860| s|@CC@|@TTPREFIX@ccppc -mlongcall| s|@HCC@|gcc| +s|@GCC@|yes| s|@LD@|@TTPREFIX@ldppc| s|@STRIP@|@TTPREFIX@stripppc| s|@SYMPREFIX@|| diff --git a/erts/autoconf/vxworks/sed.vxworks_simlinux b/erts/autoconf/vxworks/sed.vxworks_simlinux index 10cd7bbb82..06b1847602 100644 --- a/erts/autoconf/vxworks/sed.vxworks_simlinux +++ b/erts/autoconf/vxworks/sed.vxworks_simlinux @@ -36,6 +36,7 @@ s|@ARCH@|simlinux| s|@CC@|GCC_EXEC_PREFIX=@WIND_BASE@/gnu/3.4.4-vxworks-6.3/@HOST_TYPE@/lib/gcc-lib/ @WIND_BASE@/gnu/3.4.4-vxworks-6.3/@HOST_TYPE@/bin/ccpentium| s|@HCC@|gcc| +s|@GCC@|yes| s|@LD@|GCC_EXEC_PREFIX=@WIND_BASE@/gnu/3.4.4-vxworks-6.3/@HOST_TYPE@/lib/gcc-lib/ @WIND_BASE@/gnu/3.4.4-vxworks-6.3/@HOST_TYPE@/bin/ldpentium| diff --git a/erts/autoconf/vxworks/sed.vxworks_simso b/erts/autoconf/vxworks/sed.vxworks_simso index cd30f8c2b2..07606cad80 100644 --- a/erts/autoconf/vxworks/sed.vxworks_simso +++ b/erts/autoconf/vxworks/sed.vxworks_simso @@ -36,6 +36,7 @@ s|@ARCH@|simso| s|@CC@|GCC_EXEC_PREFIX=@WIND_BASE@/gnu/3.4.4-vxworks-6.3/@HOST_TYPE@/lib/gcc-lib/ @WIND_BASE@/gnu/3.4.4-vxworks-6.3/@HOST_TYPE@/bin/ccsparc| s|@HCC@|gcc| +s|@GCC@|yes| # Tornado2.2: s|@LD@|@TTPREFIX@ldsimso| s|@LD@|GCC_EXEC_PREFIX=@WIND_BASE@/gnu/3.4.4-vxworks-6.3/@HOST_TYPE@/lib/gcc-lib/ @WIND_BASE@/gnu/3.4.4-vxworks-6.3/@HOST_TYPE@/bin/ldsparc| diff --git a/erts/autoconf/vxworks/sed.vxworks_sparc b/erts/autoconf/vxworks/sed.vxworks_sparc index a3758423e8..59431fddf9 100644 --- a/erts/autoconf/vxworks/sed.vxworks_sparc +++ b/erts/autoconf/vxworks/sed.vxworks_sparc @@ -30,6 +30,7 @@ s/@host@/vxworks_sparc/ s/@system_type@/vxworks_sparc/ s/@CC@/\/home\/gandalf\/bsproj\/tools\/vw-gnu\/solaris.sparc\/bin\/ccsparc/ s/@HCC@/gcc/ +s/@GCC@/yes/ s/@LD@/\/home\/gandalf\/bsproj\/tools\/vw-gnu\/solaris.sparc\/bin\/ldsparc/ s/@DEBUG_FLAGS@/-g/ s/@GCCLIB_PATH@/\/home\/gandalf\/bsproj\/tools\/vw-gnu\/solaris.sparc\/lib\/gcc-lib\/sparc-wrs-vxworks\/cygnus-2.2.3.1\/libgcc.a/ diff --git a/erts/doc/src/Makefile b/erts/doc/src/Makefile index 3cc29e14b1..21aa3db864 100644 --- a/erts/doc/src/Makefile +++ b/erts/doc/src/Makefile @@ -149,6 +149,7 @@ debug opt: clean: rm -rf $(HTMLDIR)/* + rm -rf $(XMLDIR) rm -f $(MAN1DIR)/* rm -f $(MAN3DIR)/* rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo) diff --git a/erts/doc/src/erl_nif.xml b/erts/doc/src/erl_nif.xml index 0fff8f7cad..a20b8ee884 100644 --- a/erts/doc/src/erl_nif.xml +++ b/erts/doc/src/erl_nif.xml @@ -1250,8 +1250,9 @@ typedef struct { <fsummary>Format strings and Erlang terms.</fsummary> <desc> <p>Similar to <c>fprintf</c> but this format string also accepts - <c>"%T"</c>, which formats Erlang terms.</p> - <p>This function was originally intenden for debugging purpose. It is not + <c>"%T"</c>, which formats Erlang terms of type + <seealso marker="#ERL_NIF_TERM"><c>ERL_NIF_TERM</c></seealso>.</p> + <p>This function is primarily intenden for debugging purpose. It is not recommended to print very large terms with <c>%T</c>. The function may change <c>errno</c>, even if successful.</p> </desc> @@ -3191,8 +3192,9 @@ if (retval & ERL_NIF_SELECT_STOP_CALLED) { <fsummary>Format strings and Erlang terms.</fsummary> <desc> <p>Similar to <c>snprintf</c> but this format string also accepts - <c>"%T"</c>, which formats Erlang terms.</p> - <p>This function was originally intenden for debugging purpose. It is not + <c>"%T"</c>, which formats Erlang terms of type + <seealso marker="#ERL_NIF_TERM"><c>ERL_NIF_TERM</c></seealso>.</p> + <p>This function is primarily intenden for debugging purpose. It is not recommended to print very large terms with <c>%T</c>. The function may change <c>errno</c>, even if successful.</p> </desc> diff --git a/erts/doc/src/notes.xml b/erts/doc/src/notes.xml index 1531935f36..ebabbde70a 100644 --- a/erts/doc/src/notes.xml +++ b/erts/doc/src/notes.xml @@ -31,23 +31,68 @@ </header> <p>This document describes the changes made to the ERTS application.</p> -<section><title>Erts 10.0.2</title> +<section><title>Erts 10.0.4</title> <section><title>Fixed Bugs and Malfunctions</title> <list> <item> - <p>Fixed a rare bug that could cause processes to be - scheduled after they had been freed.</p> + <p>Fixed a bug that prevented the <c>noshell</c> option + from working correctly on Mac OS X and BSD.</p> <p> - Own Id: OTP-15067 Aux Id: ERL-573 </p> + Own Id: OTP-15169</p> + </item> + <item> + <p>Fixed a crash when matching directly against a literal + map using a single key that had been saved on the + stack.</p> + <p> + Own Id: OTP-15184</p> + </item> + <item> + <p>Fix node crash when passing a bad time option to + <c>file:read_file_info/2</c>.</p> + <p> + Own Id: OTP-15196</p> </item> </list> </section> +</section> - <section><title>Known Bugs and Problems</title> +<section><title>Erts 10.0.3</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p>Fixed a scheduler bug that caused normal schedulers to + run dirty code.</p> + <p> + Own Id: OTP-15154</p> + </item> + <item> + <p> + Fixed a bug in <c>erlang:trace_info/2</c> which caused + the emulator to crash when a bad argument was passed. The + bug was introduced in ERTS version 10.0.</p> + <p> + Own Id: OTP-15183 Aux Id: ERL-670 </p> + </item> + </list> + </section> + +</section> + +<section><title>Erts 10.0.2</title> + + <section><title>Fixed Bugs and Malfunctions</title> <list> <item> + <p>Fixed a rare bug that could cause processes to be + scheduled after they had been freed.</p> + <p> + Own Id: OTP-15067 Aux Id: ERL-573 </p> + </item> + <item> <p>Fixed a race condition in the inet driver that could cause receive to hang when the emulator was compiled with gcc 8.</p> @@ -1010,6 +1055,31 @@ </section> +<section><title>Erts 9.3.3.2</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p>Fixed a race condition in the inet driver that could + cause receive to hang when the emulator was compiled with + gcc 8.</p> + <p> + Own Id: OTP-15158 Aux Id: ERL-654 </p> + </item> + <item> + <p> + Fix bug in generation of erl_crash.dump, which could + cause VM to crash.</p> + <p> + Bug exist since erts-9.2 (OTP-20.2).</p> + <p> + Own Id: OTP-15181</p> + </item> + </list> + </section> + +</section> + <section><title>Erts 9.3.3.1</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/erts/emulator/beam/beam_ranges.c b/erts/emulator/beam/beam_ranges.c index f0c9496341..9f3153724a 100644 --- a/erts/emulator/beam/beam_ranges.c +++ b/erts/emulator/beam/beam_ranges.c @@ -35,10 +35,8 @@ typedef struct { /* * Used for crash dumping of literals. The size of erts_dump_lit_areas is - * always twice the number of active ranges (to allow for literals in both - * current and old code). + * always at least the number of active ranges. */ - ErtsLiteralArea** erts_dump_lit_areas; Uint erts_dump_num_lit_areas; @@ -180,8 +178,8 @@ erts_end_staging_ranges(int commit) (erts_aint_t) (r[dst].modules + r[dst].n / 2)); - if (r[dst].allocated * 2 > erts_dump_num_lit_areas) { - erts_dump_num_lit_areas *= 2; + if (r[dst].allocated > erts_dump_num_lit_areas) { + erts_dump_num_lit_areas = r[dst].allocated * 2; erts_dump_lit_areas = (ErtsLiteralArea **) erts_realloc(ERTS_ALC_T_CRASH_DUMP, (void *) erts_dump_lit_areas, diff --git a/erts/emulator/beam/dist.c b/erts/emulator/beam/dist.c index 70474898b2..61090e2c47 100644 --- a/erts/emulator/beam/dist.c +++ b/erts/emulator/beam/dist.c @@ -1200,21 +1200,8 @@ erts_dsig_send_group_leader(ErtsDSigData *dsdp, Eterm leader, Eterm remote) #include <valgrind/valgrind.h> #include <valgrind/memcheck.h> -#ifndef HAVE_VALGRIND_PRINTF_XML -#define VALGRIND_PRINTF_XML VALGRIND_PRINTF -#endif - # define PURIFY_MSG(msg) \ - do { \ - char buf__[1]; size_t bufsz__ = sizeof(buf__); \ - if (erts_sys_explicit_8bit_getenv("VALGRIND_LOG_XML", buf__, &bufsz__) >= 0) { \ - VALGRIND_PRINTF_XML("<erlang_error_log>" \ - "%s, line %d: %s</erlang_error_log>\n", \ - __FILE__, __LINE__, msg); \ - } else { \ - VALGRIND_PRINTF("%s, line %d: %s", __FILE__, __LINE__, msg); \ - } \ - } while (0) + VALGRIND_PRINTF("%s, line %d: %s", __FILE__, __LINE__, msg) #else # define PURIFY_MSG(msg) #endif diff --git a/erts/emulator/beam/erl_bif_info.c b/erts/emulator/beam/erl_bif_info.c index 5789fa8e71..7fada0d548 100644 --- a/erts/emulator/beam/erl_bif_info.c +++ b/erts/emulator/beam/erl_bif_info.c @@ -2093,17 +2093,6 @@ current_stacktrace(ErtsHeapFactory *hfact, Process* rp, return res; } -#if defined(VALGRIND) -static int check_if_xml(void) -{ - char buf[1]; - size_t bufsz = sizeof(buf); - return erts_sys_explicit_8bit_getenv("VALGRIND_LOG_XML", buf, &bufsz) >= 0; -} -#else -#define check_if_xml() 0 -#endif - /* * This function takes care of calls to erlang:system_info/1 when the argument * is a tuple. @@ -2200,15 +2189,9 @@ info_1_tuple(Process* BIF_P, /* Pointer to current process. */ #endif } else if (is_list(*tp)) { #if defined(PURIFY) -#define ERTS_ERROR_CHECKER_PRINTF purify_printf -#define ERTS_ERROR_CHECKER_PRINTF_XML purify_printf +# define ERTS_ERROR_CHECKER_PRINTF purify_printf #elif defined(VALGRIND) -#define ERTS_ERROR_CHECKER_PRINTF VALGRIND_PRINTF -# ifndef HAVE_VALGRIND_PRINTF_XML -# define ERTS_ERROR_CHECKER_PRINTF_XML VALGRIND_PRINTF -# else -# define ERTS_ERROR_CHECKER_PRINTF_XML VALGRIND_PRINTF_XML -# endif +# define ERTS_ERROR_CHECKER_PRINTF VALGRIND_PRINTF #endif ErlDrvSizeT buf_size = 8*1024; /* Try with 8KB first */ char *buf = erts_alloc(ERTS_ALC_T_TMP, buf_size); @@ -2224,12 +2207,7 @@ info_1_tuple(Process* BIF_P, /* Pointer to current process. */ ASSERT(r == buf_size - 1); } buf[buf_size - 1 - r] = '\0'; - if (check_if_xml()) { - ERTS_ERROR_CHECKER_PRINTF_XML("<erlang_info_log>" - "%s</erlang_info_log>\n", buf); - } else { - ERTS_ERROR_CHECKER_PRINTF("%s\n", buf); - } + ERTS_ERROR_CHECKER_PRINTF("%s\n", buf); erts_free(ERTS_ALC_T_TMP, (void *) buf); BIF_RET(am_true); #undef ERTS_ERROR_CHECKER_PRINTF diff --git a/erts/emulator/beam/erl_bif_trace.c b/erts/emulator/beam/erl_bif_trace.c index 9861483bf0..711e62c795 100644 --- a/erts/emulator/beam/erl_bif_trace.c +++ b/erts/emulator/beam/erl_bif_trace.c @@ -810,7 +810,7 @@ Eterm trace_info_2(BIF_ALIST_2) } erts_release_code_write_permission(); - if (is_internal_ref(res)) + if (is_value(res) && is_internal_ref(res)) BIF_TRAP1(erts_await_result, BIF_P, res); BIF_RET(res); diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c index 11b52526d5..8784eb5a63 100644 --- a/erts/emulator/beam/erl_process.c +++ b/erts/emulator/beam/erl_process.c @@ -9606,7 +9606,7 @@ Process *erts_schedule(ErtsSchedulerData *esdp, Process *p, int calls) ASSERT(!p->scheduler_data); p->scheduler_data = esdp; if ((!!(state & ERTS_PSFLGS_DIRTY_WORK)) - & (!(state & ERTS_PSFLG_ACTIVE_SYS))) { + & (!(state & ERTS_PSFLG_RUNNING_SYS))) { /* Migrate to dirty scheduler... */ sunlock_sched_out_proc: erts_proc_unlock(p, ERTS_PROC_LOCK_STATUS); diff --git a/erts/emulator/beam/ops.tab b/erts/emulator/beam/ops.tab index 88ede3bb60..c51e4ef784 100644 --- a/erts/emulator/beam/ops.tab +++ b/erts/emulator/beam/ops.tab @@ -1421,16 +1421,13 @@ get_map_elements Fail Src Size Rest=* | map_key_sort(Size, Rest) => \ i_get_map_elements f? s I -i_get_map_element Fail Src=xy Key=y Dst => \ - move Key x | i_get_map_element Fail Src x Dst - i_get_map_element_hash Fail Src=c Key Hash Dst => \ move Src x | i_get_map_element_hash Fail x Key Hash Dst i_get_map_element_hash f? xy c I xy i_get_map_element Fail Src=c Key Dst => \ move Src x | i_get_map_element Fail x Key Dst -i_get_map_element f? xy x xy +i_get_map_element f? xy xy xy # # Convert the plus operations to a generic plus instruction. diff --git a/erts/emulator/sys/common/erl_poll.c b/erts/emulator/sys/common/erl_poll.c index 70b5532af9..b4d1575ee5 100644 --- a/erts/emulator/sys/common/erl_poll.c +++ b/erts/emulator/sys/common/erl_poll.c @@ -803,6 +803,23 @@ update_pollset(ErtsPollSet *ps, int fd, ErtsPollOp op, ErtsPollEvents events) struct kevent evts[2]; struct timespec ts = {0, 0}; + if (op == ERTS_POLL_OP_ADD) { + /* This is a hack to make the "noshell" option work; kqueue can poll + * these fds but will not report EV_EOF, so we return NVAL to use the + * fallback instead. + * + * This may be common to all pipes but we have no way to tell whether + * an fd is a pipe or not. */ + switch (fd) { + case STDIN_FILENO: + case STDOUT_FILENO: + case STDERR_FILENO: + return ERTS_POLL_EV_NVAL; + default: + break; + } + } + #if defined(EV_DISPATCH) && !defined(__OpenBSD__) /* If we have EV_DISPATCH we use it, unless we are on OpenBSD as the behavior of EV_EOF seems to be edge triggered there and we need it diff --git a/erts/emulator/sys/unix/sys.c b/erts/emulator/sys/unix/sys.c index 189ca083d7..36579ffdb4 100644 --- a/erts/emulator/sys/unix/sys.c +++ b/erts/emulator/sys/unix/sys.c @@ -452,9 +452,9 @@ prepare_crash_dump(int secs) envsz = sizeof(env); i = erts_sys_explicit_8bit_getenv("ERL_CRASH_DUMP_NICE", env, &envsz); - if (i >= 0) { + if (i != 0) { int nice_val; - nice_val = i != 1 ? 0 : atoi(env); + nice_val = (i != 1) ? 0 : atoi(env); if (nice_val > 39) { nice_val = 39; } diff --git a/erts/emulator/test/driver_SUITE.erl b/erts/emulator/test/driver_SUITE.erl index 7aff3a6ea1..6f5d639d04 100644 --- a/erts/emulator/test/driver_SUITE.erl +++ b/erts/emulator/test/driver_SUITE.erl @@ -81,6 +81,7 @@ thr_msg_blast/1, consume_timeslice/1, env/1, + poll_pipe/1, z_test/1]). -export([bin_prefix/2]). @@ -168,6 +169,7 @@ all() -> %% Keep a_test first and z_test last... thr_msg_blast, consume_timeslice, env, + poll_pipe, z_test]. groups() -> @@ -2693,3 +2695,25 @@ rpc(Config, Fun) -> ct:fail(Other) end end. + +poll_pipe(Config) when is_list(Config) -> + %% ERL-647; we wouldn't see any events on EOF when polling a pipe using + %% kqueue(2). + case os:type() of + {unix, _} -> + Command = "erl -noshell -eval " + "'\"DATA\n\" = io:get_line(\"\")," + "eof = io:get_line(\"\")," + "halt()' <<< 'DATA'", + Ref = make_ref(), + Self = self(), + Pid = spawn(fun() -> os:cmd(Command), Self ! Ref end), + receive + Ref -> ok + after 5000 -> + exit(Pid, kill), + ct:fail("Stuck reading from stdin.") + end; + _ -> + {skipped, "Unix-only test"} + end. diff --git a/erts/emulator/test/map_SUITE.erl b/erts/emulator/test/map_SUITE.erl index f93c637650..d0a6763fe5 100644 --- a/erts/emulator/test/map_SUITE.erl +++ b/erts/emulator/test/map_SUITE.erl @@ -3080,8 +3080,19 @@ y_regs(Config) when is_list(Config) -> true = is_map(Map2) andalso is_map(Map4), + gurka = y_regs_literal(0), + gaffel = y_regs_literal(1), + ok. +y_regs_literal(Key) when is_integer(Key) -> + %% Forces the key to be placed in a Y register. + lists:seq(1, 2), + case is_map_key(Key, #{ 0 => 0 }) of + true -> gurka; + false -> gaffel + end. + y_regs_update(Map0, Val0) -> Val1 = {t,Val0}, K1 = id({key,1}), diff --git a/erts/emulator/test/trace_SUITE.erl b/erts/emulator/test/trace_SUITE.erl index 138aefb29c..979b3185a5 100644 --- a/erts/emulator/test/trace_SUITE.erl +++ b/erts/emulator/test/trace_SUITE.erl @@ -38,7 +38,8 @@ system_monitor_long_gc_1/1, system_monitor_long_gc_2/1, system_monitor_large_heap_1/1, system_monitor_large_heap_2/1, system_monitor_long_schedule/1, - bad_flag/1, trace_delivered/1, trap_exit_self_receive/1]). + bad_flag/1, trace_delivered/1, trap_exit_self_receive/1, + trace_info_badarg/1]). -include_lib("common_test/include/ct.hrl"). @@ -62,7 +63,7 @@ all() -> system_monitor_long_gc_2, system_monitor_large_heap_1, system_monitor_long_schedule, system_monitor_large_heap_2, bad_flag, trace_delivered, - trap_exit_self_receive]. + trap_exit_self_receive, trace_info_badarg]. init_per_testcase(_Case, Config) -> [{receiver,spawn(fun receiver/0)}|Config]. @@ -1734,6 +1735,10 @@ trap_exit_self_receive(Config) -> receive_nothing(), ok. +trace_info_badarg(Config) when is_list(Config) -> + catch erlang:trace_info({a,b,c},d), + ok. + drop_trace_until_down(Proc, Mon) -> drop_trace_until_down(Proc, Mon, false, 0, 0). diff --git a/erts/etc/unix/cerl.src b/erts/etc/unix/cerl.src index 896e4c8e45..2e034513b0 100644 --- a/erts/etc/unix/cerl.src +++ b/erts/etc/unix/cerl.src @@ -264,13 +264,14 @@ if [ "x$GDB" = "x" ]; then valversion=`valgrind --version` valmajor=`echo $valversion | sed 's,[a-z]*\-\([0-9]*\).*,\1,'` valminor=`echo $valversion | sed 's,[a-z]*\-[0-9]*.\([0-9]*\).*,\1,'` + valint=`echo "$valmajor * 1000 + $valminor" | bc` if [ "x$VALGRIND_LOG_XML" = "x" ]; then valgrind_xml= log_file_prefix="--log-file=" else export VALGRIND_LOG_XML valgrind_xml="--xml=yes" - if [ $valmajor -gt 2 -a $valminor -gt 4 ]; then + if [ $valint -gt 3004 ]; then log_file_prefix="--xml-file=" else log_file_prefix="--log-file=" @@ -279,7 +280,7 @@ if [ "x$GDB" = "x" ]; then if [ "x$VALGRIND_LOG_DIR" = "x" ]; then valgrind_log= else - if [ $valmajor -gt 2 -a $valminor -gt 4 ]; then + if [ $valint -gt 3004 ]; then valgrind_log="$log_file_prefix$VALGRIND_LOG_DIR/$VALGRIND_LOGFILE_PREFIX$VALGRIND_LOGFILE_INFIX$EMU_NAME.log.$$" else valgrind_log="$log_file_prefix$VALGRIND_LOG_DIR/$VALGRIND_LOGFILE_PREFIX$VALGRIND_LOGFILE_INFIX$EMU_NAME.log" diff --git a/erts/preloaded/ebin/prim_file.beam b/erts/preloaded/ebin/prim_file.beam Binary files differindex f375c05c99..3316e4348c 100644 --- a/erts/preloaded/ebin/prim_file.beam +++ b/erts/preloaded/ebin/prim_file.beam diff --git a/erts/preloaded/src/prim_file.erl b/erts/preloaded/src/prim_file.erl index 41ff38359c..517ca74301 100644 --- a/erts/preloaded/src/prim_file.erl +++ b/erts/preloaded/src/prim_file.erl @@ -580,15 +580,20 @@ read_link_info(Name, Opts) -> read_info_1(Name, 0, proplist_get_value(time, Opts, local)). read_info_1(Name, FollowLinks, TimeType) -> - try read_info_nif(encode_path(Name), FollowLinks) of - {error, Reason} -> {error, Reason}; - FileInfo -> - CTime = from_posix_seconds(FileInfo#file_info.ctime, TimeType), - MTime = from_posix_seconds(FileInfo#file_info.mtime, TimeType), - ATime = from_posix_seconds(FileInfo#file_info.atime, TimeType), - {ok, FileInfo#file_info{ ctime = CTime, mtime = MTime, atime = ATime }} + try + case read_info_nif(encode_path(Name), FollowLinks) of + {error, Reason} -> + {error, Reason}; + FileInfo -> + CTime = from_posix_seconds(FileInfo#file_info.ctime, TimeType), + MTime = from_posix_seconds(FileInfo#file_info.mtime, TimeType), + ATime = from_posix_seconds(FileInfo#file_info.atime, TimeType), + {ok, FileInfo#file_info{ ctime = CTime, + mtime = MTime, + atime = ATime }} + end catch - error:badarg -> {error, badarg} + error:_ -> {error, badarg} end. write_file_info(Filename, Info) -> diff --git a/erts/vsn.mk b/erts/vsn.mk index 1df1b9142b..ac464ea165 100644 --- a/erts/vsn.mk +++ b/erts/vsn.mk @@ -18,7 +18,7 @@ # %CopyrightEnd% # -VSN = 10.0.2 +VSN = 10.0.4 # Port number 4365 in 4.2 # Port number 4366 in 4.3 diff --git a/lib/Makefile b/lib/Makefile index 0053238826..cdb3f3f3dc 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -58,7 +58,7 @@ else SUB_DIRECTORIES = hipe parsetools asn1/src else ifdef TERTIARY_BOOTSTRAP - SUB_DIRECTORIES = snmp sasl jinterface ic syntax_tools wx + SUB_DIRECTORIES = snmp sasl jinterface syntax_tools wx else ifdef DOC_BOOTSTRAP SUB_DIRECTORIES = xmerl edoc erl_docgen diff --git a/lib/asn1/doc/src/Makefile b/lib/asn1/doc/src/Makefile index f200c4aae2..9c0d865884 100644 --- a/lib/asn1/doc/src/Makefile +++ b/lib/asn1/doc/src/Makefile @@ -107,6 +107,7 @@ html: gifs $(HTML_REF_MAN_FILE) clean clean_docs: rm -rf $(HTMLDIR)/* + rm -rf $(XMLDIR) rm -f $(MAN3DIR)/* rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo) rm -f $(GEN_XML) errs core *~ diff --git a/lib/common_test/doc/src/Makefile b/lib/common_test/doc/src/Makefile index 293ef591cb..4d6161d3ae 100644 --- a/lib/common_test/doc/src/Makefile +++ b/lib/common_test/doc/src/Makefile @@ -140,6 +140,7 @@ debug opt: clean clean_docs: rm -rf $(HTMLDIR)/* + rm -rf $(XMLDIR) rm -f $(MAN1DIR)/* rm -f $(MAN3DIR)/* rm -f $(MAN6DIR)/* diff --git a/lib/common_test/src/cth_log_redirect.erl b/lib/common_test/src/cth_log_redirect.erl index 99c484de48..4980d1ee4b 100644 --- a/lib/common_test/src/cth_log_redirect.erl +++ b/lib/common_test/src/cth_log_redirect.erl @@ -184,21 +184,12 @@ handle_call({log,#{meta:=#{gl:=GL}},_}, _From, {reply, ok, State}; handle_call({log, - #{msg:=Msg0, - meta:=#{?MODULE:=#{category:=Category}}=Meta}=Log, + #{meta:=#{?MODULE:=#{category:=Category}}}=Log, #{formatter:={Formatter,FConfig}}}, _From, #eh_state{log_func=LogFunc}=State) -> Header = format_header(State), - Msg = - case Msg0 of - {report,R} -> - Fun=maps:get(report_cb,Meta,fun logger:format_report/1), - Fun(R); - _ -> - Msg0 - end, - String = Formatter:format(Log#{msg=>Msg},FConfig), + String = Formatter:format(Log,FConfig), case LogFunc of tc_log -> ct_logs:tc_log(Category, ?STD_IMPORTANCE, diff --git a/lib/compiler/doc/src/Makefile b/lib/compiler/doc/src/Makefile index 13210de040..661415899f 100644 --- a/lib/compiler/doc/src/Makefile +++ b/lib/compiler/doc/src/Makefile @@ -89,6 +89,7 @@ debug opt: clean clean_docs: rm -rf $(HTMLDIR)/* + rm -rf $(XMLDIR) rm -f $(MAN3DIR)/* rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo) rm -f errs core *~ diff --git a/lib/compiler/src/v3_core.erl b/lib/compiler/src/v3_core.erl index 0196e7fdfd..3b746ab5bf 100644 --- a/lib/compiler/src/v3_core.erl +++ b/lib/compiler/src/v3_core.erl @@ -1501,7 +1501,7 @@ bc_initial_size(E0, Q, St0) -> end. bc_elem_size({bin,_,El}, St0) -> - case bc_elem_size_1(El, 0, []) of + case bc_elem_size_1(El, ordsets:new(), 0, []) of {Bits,[]} -> {#c_literal{val=Bits},[],[],St0}; {Bits,Vars0} -> @@ -1515,19 +1515,33 @@ bc_elem_size(_, _) -> throw(impossible). bc_elem_size_1([{bin_element,_,{string,_,String},{integer,_,N},_}=El|Es], - Bits, Vars) -> + DefVars, Bits, SizeVars) -> U = get_unit(El), - bc_elem_size_1(Es, Bits+U*N*length(String), Vars); -bc_elem_size_1([{bin_element,_,_,{integer,_,N},_}=El|Es], Bits, Vars) -> + bc_elem_size_1(Es, DefVars, Bits+U*N*length(String), SizeVars); +bc_elem_size_1([{bin_element,_,Expr,{integer,_,N},_}=El|Es], + DefVars0, Bits, SizeVars) -> U = get_unit(El), - bc_elem_size_1(Es, Bits+U*N, Vars); -bc_elem_size_1([{bin_element,_,_,{var,_,Var},_}=El|Es], Bits, Vars) -> - U = get_unit(El), - bc_elem_size_1(Es, Bits, [{U,#c_var{name=Var}}|Vars]); -bc_elem_size_1([_|_], _, _) -> + DefVars = bc_elem_size_def_var(Expr, DefVars0), + bc_elem_size_1(Es, DefVars, Bits+U*N, SizeVars); +bc_elem_size_1([{bin_element,_,Expr,{var,_,Src},_}=El|Es], + DefVars0, Bits, SizeVars) -> + case ordsets:is_element(Src, DefVars0) of + false -> + U = get_unit(El), + DefVars = bc_elem_size_def_var(Expr, DefVars0), + bc_elem_size_1(Es, DefVars, Bits, [{U,#c_var{name=Src}}|SizeVars]); + true -> + throw(impossible) + end; +bc_elem_size_1([_|_], _, _, _) -> throw(impossible); -bc_elem_size_1([], Bits, Vars) -> - {Bits,Vars}. +bc_elem_size_1([], _DefVars, Bits, SizeVars) -> + {Bits,SizeVars}. + +bc_elem_size_def_var({var,_,Var}, DefVars) -> + ordsets:add_element(Var, DefVars); +bc_elem_size_def_var(_Expr, DefVars) -> + DefVars. bc_elem_size_combine([{U,V}|T], U, UVars, Acc) -> bc_elem_size_combine(T, U, [V|UVars], Acc); diff --git a/lib/compiler/test/bs_bincomp_SUITE.erl b/lib/compiler/test/bs_bincomp_SUITE.erl index 42361ea546..a5d49020a9 100644 --- a/lib/compiler/test/bs_bincomp_SUITE.erl +++ b/lib/compiler/test/bs_bincomp_SUITE.erl @@ -26,7 +26,7 @@ init_per_group/2,end_per_group/2, byte_aligned/1,bit_aligned/1,extended_byte_aligned/1, extended_bit_aligned/1,mixed/1,filters/1,trim_coverage/1, - nomatch/1,sizes/1,general_expressions/1]). + nomatch/1,sizes/1,general_expressions/1,matched_out_size/1]). -include_lib("common_test/include/ct.hrl"). @@ -35,7 +35,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}]. all() -> [byte_aligned, bit_aligned, extended_byte_aligned, extended_bit_aligned, mixed, filters, trim_coverage, - nomatch, sizes, general_expressions]. + nomatch, sizes, general_expressions, matched_out_size]. groups() -> []. @@ -338,6 +338,13 @@ general_expressions(_) -> -undef(BAD). +matched_out_size(Config) when is_list(Config) -> + <<1, 2>> = matched_out_size_1(<<4, 1:4, 4, 2:4>>), + ok. + +matched_out_size_1(Binary) -> + << <<X>> || <<S, X:S>> <= Binary>>. + cs_init() -> erts_debug:set_internal_state(available_internal_state, true), ok. diff --git a/lib/crypto/doc/src/Makefile b/lib/crypto/doc/src/Makefile index aa987d2b39..2148062e78 100644 --- a/lib/crypto/doc/src/Makefile +++ b/lib/crypto/doc/src/Makefile @@ -89,6 +89,7 @@ debug opt valgrind: clean clean_docs clean_tex: rm -rf $(HTMLDIR)/* + rm -rf $(XMLDIR) rm -f $(MAN3DIR)/* rm -f $(MAN6DIR)/* rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo) diff --git a/lib/debugger/doc/src/Makefile b/lib/debugger/doc/src/Makefile index 4a25006ee0..56d6085e9c 100644 --- a/lib/debugger/doc/src/Makefile +++ b/lib/debugger/doc/src/Makefile @@ -99,6 +99,7 @@ gifs: $(GIF_FILES:%=$(HTMLDIR)/%) clean clean_docs: rm -rf $(HTMLDIR)/* + rm -rf $(XMLDIR) rm -f $(MAN3DIR)/* rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo) rm -f errs core *~ diff --git a/lib/dialyzer/doc/src/Makefile b/lib/dialyzer/doc/src/Makefile index 3463b589e6..3ce777392b 100644 --- a/lib/dialyzer/doc/src/Makefile +++ b/lib/dialyzer/doc/src/Makefile @@ -91,6 +91,7 @@ debug opt: clean clean_docs: rm -rf $(HTMLDIR)/* + rm -rf $(XMLDIR) rm -f $(MAN3DIR)/* rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo) rm -f errs core *~ diff --git a/lib/diameter/doc/src/Makefile b/lib/diameter/doc/src/Makefile index 7a7546fc4d..7672598060 100644 --- a/lib/diameter/doc/src/Makefile +++ b/lib/diameter/doc/src/Makefile @@ -77,6 +77,7 @@ clean_man: clean_html: rm -rf $(HTMLDIR)/* + rm -rf $(XMLDIR) gifs: $(GIF_FILES:%=$(HTMLDIR)/%) diff --git a/lib/edoc/doc/src/Makefile b/lib/edoc/doc/src/Makefile index 71de42795a..aba94a6802 100644 --- a/lib/edoc/doc/src/Makefile +++ b/lib/edoc/doc/src/Makefile @@ -114,6 +114,7 @@ debug opt: clean clean_docs: rm -rf $(HTMLDIR)/* + rm -rf $(XMLDIR) rm -f $(MAN3DIR)/* rm -f $(XML_REF3_FILES) $(XML_CHAPTER_FILES) *.html rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo) diff --git a/lib/eldap/doc/src/Makefile b/lib/eldap/doc/src/Makefile index aff1da4a9a..bf1eca267a 100644 --- a/lib/eldap/doc/src/Makefile +++ b/lib/eldap/doc/src/Makefile @@ -89,6 +89,7 @@ debug opt valgrind: clean clean_docs clean_tex: rm -rf $(HTMLDIR)/* + rm -rf $(XMLDIR) rm -f $(MAN3DIR)/* rm -f $(MAN6DIR)/* rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo) diff --git a/lib/erl_docgen/doc/src/Makefile b/lib/erl_docgen/doc/src/Makefile index a9110e4635..d6d2550425 100644 --- a/lib/erl_docgen/doc/src/Makefile +++ b/lib/erl_docgen/doc/src/Makefile @@ -106,6 +106,7 @@ html: gifs examples $(HTML_REF_MAN_FILE) clean clean_docs: rm -rf $(HTMLDIR)/* + rm -rf $(XMLDIR) rm -f $(MAN6DIR)/* rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo) rm -f errs core *~ diff --git a/lib/erl_interface/doc/src/Makefile b/lib/erl_interface/doc/src/Makefile index 8ef7e9648c..173bd2e83b 100644 --- a/lib/erl_interface/doc/src/Makefile +++ b/lib/erl_interface/doc/src/Makefile @@ -100,6 +100,7 @@ debug opt: clean clean_docs clean_tex: rm -rf $(HTMLDIR)/* + rm -rf $(XMLDIR) rm -f $(MAN1DIR)/* rm -f $(MAN3DIR)/* rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo) diff --git a/lib/erl_interface/src/connect/ei_connect.c b/lib/erl_interface/src/connect/ei_connect.c index 34f4620866..9df4fa3b6c 100644 --- a/lib/erl_interface/src/connect/ei_connect.c +++ b/lib/erl_interface/src/connect/ei_connect.c @@ -138,6 +138,11 @@ static int recv_name(int fd, unsigned *version, unsigned *flags, ErlConnect *namebuf, unsigned ms); +static struct hostent* +dyn_gethostbyname_r(const char *name, struct hostent *hostp, char **buffer_p, + int buflen, int *h_errnop); + + /*************************************************************************** * @@ -480,10 +485,14 @@ int ei_connect_xinit(ei_cnode* ec, const char *thishostname, int ei_connect_init(ei_cnode* ec, const char* this_node_name, const char *cookie, short creation) { - struct hostent *hp; char thishostname[EI_MAXHOSTNAMELEN+1]; char thisnodename[MAXNODELEN+1]; char thisalivename[EI_MAXALIVELEN+1]; + struct hostent host, *hp; + char buffer[1024]; + char *buf = buffer; + int ei_h_errno; + int res; #ifdef __WIN32__ if (!initWinSock()) { @@ -517,10 +526,13 @@ int ei_connect_init(ei_cnode* ec, const char* this_node_name, strcpy(thisalivename, this_node_name); } - if ((hp = ei_gethostbyname(thishostname)) == 0) { + hp = dyn_gethostbyname_r(thishostname,&host,&buf,sizeof(buffer),&ei_h_errno); + if (hp == NULL) { /* Looking up IP given hostname fails. We must be on a standalone host so let's use loopback for communication instead. */ - if ((hp = ei_gethostbyname("localhost")) == 0) { + hp = dyn_gethostbyname_r("localhost", &host, &buf, sizeof(buffer), + &ei_h_errno); + if (hp == NULL) { #ifdef __WIN32__ char reason[1024]; @@ -549,8 +561,11 @@ int ei_connect_init(ei_cnode* ec, const char* this_node_name, sprintf(thisnodename, "%s@%s", this_node_name, hp->h_name); } } - return ei_connect_xinit(ec, thishostname, thisalivename, thisnodename, - (struct in_addr *)*hp->h_addr_list, cookie, creation); + res = ei_connect_xinit(ec, thishostname, thisalivename, thisnodename, + (struct in_addr *)*hp->h_addr_list, cookie, creation); + if (buf != buffer) + free(buf); + return res; } @@ -595,6 +610,13 @@ struct hostent *dyn_gethostbyname_r(const char *name, int buflen, int *h_errnop) { +#ifdef __WIN32__ + /* + * Apparently ei_gethostbyname_r not implemented for Windows (?) + * Fall back on ei_gethostbyname like before. + */ + return ei_gethostbyname(name); +#else char* buf = *buffer_p; struct hostent *hp; @@ -629,6 +651,7 @@ struct hostent *dyn_gethostbyname_r(const char *name, } } return hp; +#endif } /* @@ -999,7 +1022,7 @@ int ei_do_receive_msg(int fd, int staticbuffer_p, erl_errno = EMSGSIZE; return ERL_ERROR; } - x->index = x->buffsz; + x->index = msglen; switch (msg->msgtype) { /* FIXME does not handle trace tokens and monitors */ case ERL_SEND: case ERL_REG_SEND: diff --git a/lib/erl_interface/src/misc/ei_pthreads.c b/lib/erl_interface/src/misc/ei_pthreads.c index 25608edeec..8b34364659 100644 --- a/lib/erl_interface/src/misc/ei_pthreads.c +++ b/lib/erl_interface/src/misc/ei_pthreads.c @@ -206,6 +206,7 @@ volatile int *__erl_errno_place(void) use_fallback = 1; return &fallback_errno; } + *erl_errno_p = 0; if (pthread_setspecific(erl_errno_key, erl_errno_p) != 0 || (erl_errno_p = pthread_getspecific(erl_errno_key)) == NULL) { diff --git a/lib/erl_interface/test/ei_accept_SUITE.erl b/lib/erl_interface/test/ei_accept_SUITE.erl index 85c567acd3..78a433d21b 100644 --- a/lib/erl_interface/test/ei_accept_SUITE.erl +++ b/lib/erl_interface/test/ei_accept_SUITE.erl @@ -25,6 +25,7 @@ -include("ei_accept_SUITE_data/ei_accept_test_cases.hrl"). -export([all/0, suite/0, + init_per_testcase/2, ei_accept/1, ei_threaded_accept/1, monitor_ei_process/1]). @@ -38,8 +39,11 @@ all() -> [ei_accept, ei_threaded_accept, monitor_ei_process]. +init_per_testcase(Case, Config) -> + runner:init_per_testcase(?MODULE, Case, Config). + ei_accept(Config) when is_list(Config) -> - P = runner:start(?interpret), + P = runner:start(Config, ?interpret), 0 = ei_connect_init(P, 42, erlang:get_cookie(), 0), Myname = hd(tl(string:tokens(atom_to_list(node()), "@"))), @@ -91,7 +95,7 @@ ei_threaded_accept(Config) when is_list(Config) -> %% Test erlang:monitor toward erl_interface "processes" monitor_ei_process(Config) when is_list(Config) -> - P = runner:start(?interpret), + P = runner:start(Config, ?interpret), 0 = ei_connect_init(P, 42, erlang:get_cookie(), 0), Myname = hd(tl(string:tokens(atom_to_list(node()), "@"))), @@ -99,7 +103,6 @@ monitor_ei_process(Config) when is_list(Config) -> EINode = list_to_atom("c42@"++Myname), io:format("EINode ~p ~n", [EINode]), - Self = self(), Port = 6543, {ok, ListenFd} = ei_publish(P, Port), MRef1 = erlang:monitor(process, {any, EINode}), diff --git a/lib/erl_interface/test/ei_accept_SUITE_data/ei_accept_test.c b/lib/erl_interface/test/ei_accept_SUITE_data/ei_accept_test.c index 04bba90732..50df848b69 100644 --- a/lib/erl_interface/test/ei_accept_SUITE_data/ei_accept_test.c +++ b/lib/erl_interface/test/ei_accept_SUITE_data/ei_accept_test.c @@ -75,11 +75,7 @@ TESTCASE(interpret) ei_term term; ei_x_new(&x); - for (;;) { - if (get_bin_term(&x, &term)) { - report(1); - return; - } else { + while (get_bin_term(&x, &term) == 0) { char* buf = x.buff, func[MAXATOMLEN]; int index = x.index, arity; if (term.ei_type != ERL_SMALL_TUPLE_EXT || term.arity != 2) @@ -100,8 +96,9 @@ TESTCASE(interpret) message("\"%d\" \n", func); fail("bad command"); } - } - } + } + report(1); + ei_x_free(&x); } static void cmd_ei_connect_init(char* buf, int len) diff --git a/lib/erl_interface/test/ei_connect_SUITE.erl b/lib/erl_interface/test/ei_connect_SUITE.erl index 66498deadc..24cd384295 100644 --- a/lib/erl_interface/test/ei_connect_SUITE.erl +++ b/lib/erl_interface/test/ei_connect_SUITE.erl @@ -25,6 +25,7 @@ -include("ei_connect_SUITE_data/ei_connect_test_cases.hrl"). -export([all/0, suite/0, + init_per_testcase/2, ei_send/1, ei_reg_send/1, ei_format_pid/1, @@ -44,8 +45,11 @@ all() -> [ei_send, ei_reg_send, ei_rpc, ei_format_pid, ei_send_funs, ei_threaded_send, ei_set_get_tracelevel]. +init_per_testcase(Case, Config) -> + runner:init_per_testcase(?MODULE, Case, Config). + ei_send(Config) when is_list(Config) -> - P = runner:start(?interpret), + P = runner:start(Config, ?interpret), 0 = ei_connect_init(P, 42, erlang:get_cookie(), 0), {ok,Fd} = ei_connect(P, node()), @@ -58,7 +62,7 @@ ei_send(Config) when is_list(Config) -> ei_format_pid(Config) when is_list(Config) -> S = self(), - P = runner:start(?interpret), + P = runner:start(Config, ?interpret), 0 = ei_connect_init(P, 42, erlang:get_cookie(), 0), {ok,Fd} = ei_connect(P, node()), @@ -70,7 +74,7 @@ ei_format_pid(Config) when is_list(Config) -> ok. ei_send_funs(Config) when is_list(Config) -> - P = runner:start(?interpret), + P = runner:start(Config, ?interpret), 0 = ei_connect_init(P, 42, erlang:get_cookie(), 0), {ok,Fd} = ei_connect(P, node()), @@ -88,7 +92,7 @@ ei_send_funs(Config) when is_list(Config) -> ok. ei_reg_send(Config) when is_list(Config) -> - P = runner:start(?interpret), + P = runner:start(Config, ?interpret), 0 = ei_connect_init(P, 42, erlang:get_cookie(), 0), {ok,Fd} = ei_connect(P, node()), @@ -137,7 +141,7 @@ start_einode(Einode, N, Host) -> ok. ei_rpc(Config) when is_list(Config) -> - P = runner:start(?interpret), + P = runner:start(Config, ?interpret), 0 = ei_connect_init(P, 42, erlang:get_cookie(), 0), {ok,Fd} = ei_connect(P, node()), @@ -150,7 +154,7 @@ ei_rpc(Config) when is_list(Config) -> ok. ei_set_get_tracelevel(Config) when is_list(Config) -> - P = runner:start(?interpret), + P = runner:start(Config, ?interpret), 5 = ei_set_get_tracelevel(P, 5), 0 = ei_connect_init(P, 42, erlang:get_cookie(), 0), {ok,Fd} = ei_connect(P, node()), diff --git a/lib/erl_interface/test/ei_connect_SUITE_data/ei_connect_test.c b/lib/erl_interface/test/ei_connect_SUITE_data/ei_connect_test.c index 6a3796dd24..fbd86cdb50 100644 --- a/lib/erl_interface/test/ei_connect_SUITE_data/ei_connect_test.c +++ b/lib/erl_interface/test/ei_connect_SUITE_data/ei_connect_test.c @@ -74,11 +74,7 @@ TESTCASE(interpret) ei_term term; ei_x_new(&x); - for (;;) { - if (get_bin_term(&x, &term)) { - report(1); - return; - } else { + while (get_bin_term(&x, &term) == 0) { char* buf = x.buff, func[MAXATOMLEN]; int index = x.index, arity; if (term.ei_type != ERL_SMALL_TUPLE_EXT || term.arity != 2) @@ -99,8 +95,10 @@ TESTCASE(interpret) message("\"%d\" \n", func); fail("bad command"); } - } - } + } + report(1); + ei_x_free(&x); + return; } diff --git a/lib/erl_interface/test/ei_decode_SUITE.erl b/lib/erl_interface/test/ei_decode_SUITE.erl index 74fb9b8916..499f10611e 100644 --- a/lib/erl_interface/test/ei_decode_SUITE.erl +++ b/lib/erl_interface/test/ei_decode_SUITE.erl @@ -25,6 +25,7 @@ -include("ei_decode_SUITE_data/ei_decode_test_cases.hrl"). -export([all/0, suite/0, + init_per_testcase/2, test_ei_decode_long/1, test_ei_decode_ulong/1, test_ei_decode_longlong/1, @@ -42,6 +43,9 @@ all() -> test_ei_decode_char, test_ei_decode_nonoptimal, test_ei_decode_misc, test_ei_decode_utf8_atom]. +init_per_testcase(Case, Config) -> + runner:init_per_testcase(?MODULE, Case, Config). + %% --------------------------------------------------------------------------- % NOTE: for historical reasons we don't pach as tight as we can, @@ -51,7 +55,7 @@ all() -> %% ######################################################################## %% test_ei_decode_long(Config) when is_list(Config) -> - P = runner:start(?test_ei_decode_long), + P = runner:start(Config, ?test_ei_decode_long), send_integers(P), runner:recv_eot(P), ok. @@ -60,7 +64,7 @@ test_ei_decode_long(Config) when is_list(Config) -> %% ######################################################################## %% test_ei_decode_ulong(Config) when is_list(Config) -> - P = runner:start(?test_ei_decode_ulong), + P = runner:start(Config, ?test_ei_decode_ulong), send_integers(P), runner:recv_eot(P), ok. @@ -77,7 +81,7 @@ test_ei_decode_longlong(Config) when is_list(Config) -> vxworks -> {skip,"Skipped on VxWorks"}; _ -> - P = runner:start(?test_ei_decode_longlong), + P = runner:start(Config, ?test_ei_decode_longlong), send_integers2(P), runner:recv_eot(P), ok @@ -91,7 +95,7 @@ test_ei_decode_ulonglong(Config) when is_list(Config) -> vxworks -> {skip,"Skipped on VxWorks"}; _ -> - P = runner:start(?test_ei_decode_ulonglong), + P = runner:start(Config, ?test_ei_decode_ulonglong), send_integers2(P), runner:recv_eot(P), ok @@ -104,7 +108,7 @@ test_ei_decode_ulonglong(Config) when is_list(Config) -> %% FIXME maybe the API should change to use "unsigned char" to be clear?! test_ei_decode_char(Config) when is_list(Config) -> - P = runner:start(?test_ei_decode_char), + P = runner:start(Config, ?test_ei_decode_char), send_term_as_binary(P,0), send_term_as_binary(P,16#7f), @@ -119,7 +123,7 @@ test_ei_decode_char(Config) when is_list(Config) -> %% ######################################################################## %% test_ei_decode_nonoptimal(Config) when is_list(Config) -> - P = runner:start(?test_ei_decode_nonoptimal), + P = runner:start(Config, ?test_ei_decode_nonoptimal), send_non_optimal_pos(P), % decode_char send_non_optimal(P), % decode_long @@ -168,7 +172,7 @@ send_non_optimal_neg(P) -> %% ######################################################################## %% test_ei_decode_misc(Config) when is_list(Config) -> - P = runner:start(?test_ei_decode_misc), + P = runner:start(Config, ?test_ei_decode_misc), send_term_as_binary(P,0.0), send_term_as_binary(P,-1.0), @@ -199,7 +203,7 @@ test_ei_decode_misc(Config) when is_list(Config) -> %% ######################################################################## %% test_ei_decode_utf8_atom(Config) -> - P = runner:start(?test_ei_decode_utf8_atom), + P = runner:start(Config, ?test_ei_decode_utf8_atom), send_latin1_atom_as_binary(P,"å"), send_latin1_atom_as_binary(P,"ä"), diff --git a/lib/erl_interface/test/ei_decode_SUITE_data/ei_decode_test.c b/lib/erl_interface/test/ei_decode_SUITE_data/ei_decode_test.c index b7a2c4bb8b..5a9be1e9a2 100644 --- a/lib/erl_interface/test/ei_decode_SUITE_data/ei_decode_test.c +++ b/lib/erl_interface/test/ei_decode_SUITE_data/ei_decode_test.c @@ -105,6 +105,7 @@ int ei_decode_my_string(const char *buf, int *index, char *to, fail1("size of encoded data (%d) is incorrect", size1); \ return; \ } \ + free_packet(buf); \ } \ #define EI_DECODE_2_FAIL(FUNC,SIZE,TYPE,VAL) \ @@ -148,6 +149,7 @@ int ei_decode_my_string(const char *buf, int *index, char *to, fail("size of encoded data should be 0"); \ return; \ } \ + free_packet(buf); \ } \ #define dump(arr, num) { \ @@ -205,6 +207,7 @@ int ei_decode_my_string(const char *buf, int *index, char *to, fail("size of encoded data is incorrect"); \ return; \ } \ + free_packet(buf); \ } \ #define EI_DECODE_STRING(FUNC,SIZE,VAL) \ @@ -248,6 +251,7 @@ int ei_decode_my_string(const char *buf, int *index, char *to, fail("size of encoded data should be 0"); \ return; \ } \ + free_packet(buf); \ } \ //#define EI_DECODE_UTF8_STRING(FUNC,SIZE,VAL) @@ -310,6 +314,7 @@ int ei_decode_my_string(const char *buf, int *index, char *to, fail("size of encoded data is incorrect"); \ return; \ } \ + free_packet(buf); \ } \ /* ******************************************************************** */ diff --git a/lib/erl_interface/test/ei_decode_encode_SUITE.erl b/lib/erl_interface/test/ei_decode_encode_SUITE.erl index 160720b413..6476e92be9 100644 --- a/lib/erl_interface/test/ei_decode_encode_SUITE.erl +++ b/lib/erl_interface/test/ei_decode_encode_SUITE.erl @@ -25,6 +25,7 @@ -include("ei_decode_encode_SUITE_data/ei_decode_encode_test_cases.hrl"). -export([all/0, suite/0, + init_per_testcase/2, test_ei_decode_encode/1]). suite() -> @@ -33,6 +34,9 @@ suite() -> all() -> [test_ei_decode_encode]. +init_per_testcase(Case, Config) -> + runner:init_per_testcase(?MODULE, Case, Config). + %% --------------------------------------------------------------------------- % NOTE: these types have no meaning on the C side so we pass them @@ -42,7 +46,7 @@ all() -> %% ######################################################################## %% test_ei_decode_encode(Config) when is_list(Config) -> - P = runner:start(?test_ei_decode_encode), + P = runner:start(Config, ?test_ei_decode_encode), Fun = fun (X) -> {X,true} end, Pid = self(), diff --git a/lib/erl_interface/test/ei_decode_encode_SUITE_data/ei_decode_encode_test.c b/lib/erl_interface/test/ei_decode_encode_SUITE_data/ei_decode_encode_test.c index 467f789fdb..6285b5e199 100644 --- a/lib/erl_interface/test/ei_decode_encode_SUITE_data/ei_decode_encode_test.c +++ b/lib/erl_interface/test/ei_decode_encode_SUITE_data/ei_decode_encode_test.c @@ -466,6 +466,7 @@ void decode_encode_big(struct Type* t) send_buffer(arg.buff, arg.index); ei_x_free(&arg); ei_free_big(p); + free_packet(buf); } diff --git a/lib/erl_interface/test/ei_encode_SUITE.erl b/lib/erl_interface/test/ei_encode_SUITE.erl index 8857b092f3..8c3b0e193b 100644 --- a/lib/erl_interface/test/ei_encode_SUITE.erl +++ b/lib/erl_interface/test/ei_encode_SUITE.erl @@ -25,6 +25,7 @@ -include("ei_encode_SUITE_data/ei_encode_test_cases.hrl"). -export([all/0, suite/0, + init_per_testcase/2, test_ei_encode_long/1, test_ei_encode_ulong/1, test_ei_encode_longlong/1, @@ -45,6 +46,9 @@ all() -> test_ei_encode_fails, test_ei_encode_utf8_atom, test_ei_encode_utf8_atom_len]. +init_per_testcase(Case, Config) -> + runner:init_per_testcase(?MODULE, Case, Config). + %% --------------------------------------------------------------------------- @@ -55,7 +59,7 @@ all() -> %% ######################################################################## %% test_ei_encode_long(Config) when is_list(Config) -> - P = runner:start(?test_ei_encode_long), + P = runner:start(Config, ?test_ei_encode_long), {<<97,0>> ,0} = get_buf_and_term(P), {<<97,255>> ,255} = get_buf_and_term(P), @@ -77,7 +81,7 @@ test_ei_encode_long(Config) when is_list(Config) -> %% ######################################################################## %% test_ei_encode_ulong(Config) when is_list(Config) -> - P = runner:start(?test_ei_encode_ulong), + P = runner:start(Config, ?test_ei_encode_ulong), {<<97,0>> ,0} = get_buf_and_term(P), {<<97,255>> ,255} = get_buf_and_term(P), @@ -101,7 +105,7 @@ test_ei_encode_longlong(Config) when is_list(Config) -> vxworks -> {skip,"Skipped on VxWorks"}; _ -> - P = runner:start(?test_ei_encode_longlong), + P = runner:start(Config, ?test_ei_encode_longlong), {<<97,0>> ,0} = get_buf_and_term(P), {<<97,255>> ,255} = get_buf_and_term(P), @@ -132,7 +136,7 @@ test_ei_encode_ulonglong(Config) when is_list(Config) -> vxworks -> {skip,"Skipped on VxWorks"}; _ -> - P = runner:start(?test_ei_encode_ulonglong), + P = runner:start(Config, ?test_ei_encode_ulonglong), {<<97,0>> ,0} = get_buf_and_term(P), {<<97,255>> ,255} = get_buf_and_term(P), @@ -158,7 +162,7 @@ test_ei_encode_ulonglong(Config) when is_list(Config) -> %% FIXME maybe the API should change to use "unsigned char" to be clear?! test_ei_encode_char(Config) when is_list(Config) -> - P = runner:start(?test_ei_encode_char), + P = runner:start(Config, ?test_ei_encode_char), {<<97, 0>>,0} = get_buf_and_term(P), {<<97,127>>,16#7f} = get_buf_and_term(P), @@ -171,7 +175,7 @@ test_ei_encode_char(Config) when is_list(Config) -> %% ######################################################################## %% test_ei_encode_misc(Config) when is_list(Config) -> - P = runner:start(?test_ei_encode_misc), + P = runner:start(Config, ?test_ei_encode_misc), <<131>> = get_binaries(P), @@ -217,7 +221,7 @@ test_ei_encode_misc(Config) when is_list(Config) -> %% ######################################################################## %% test_ei_encode_fails(Config) when is_list(Config) -> - P = runner:start(?test_ei_encode_fails), + P = runner:start(Config, ?test_ei_encode_fails), XAtom = list_to_atom(lists:duplicate(255, $x)), YAtom = list_to_atom(lists:duplicate(255, $y)), @@ -236,7 +240,7 @@ test_ei_encode_fails(Config) when is_list(Config) -> %% ######################################################################## %% test_ei_encode_utf8_atom(Config) -> - P = runner:start(?test_ei_encode_utf8_atom), + P = runner:start(Config, ?test_ei_encode_utf8_atom), {<<119,2,195,133>>,'Å'} = get_buf_and_term(P), {<<119,2,195,133>>,'Å'} = get_buf_and_term(P), @@ -251,7 +255,7 @@ test_ei_encode_utf8_atom(Config) -> %% ######################################################################## %% test_ei_encode_utf8_atom_len(Config) -> - P = runner:start(?test_ei_encode_utf8_atom_len), + P = runner:start(Config, ?test_ei_encode_utf8_atom_len), {<<119,2,195,133>>,'Å'} = get_buf_and_term(P), {<<119,4,195,133,195,132>>,'ÅÄ'} = get_buf_and_term(P), diff --git a/lib/erl_interface/test/ei_format_SUITE.erl b/lib/erl_interface/test/ei_format_SUITE.erl index 07ee479b1f..b11a6ff164 100644 --- a/lib/erl_interface/test/ei_format_SUITE.erl +++ b/lib/erl_interface/test/ei_format_SUITE.erl @@ -26,6 +26,7 @@ -export([format_wo_ver/1, all/0, suite/0, + init_per_testcase/2, atoms/1, tuples/1, lists/1]). @@ -41,10 +42,13 @@ suite() -> all() -> [format_wo_ver, atoms, tuples, lists]. +init_per_testcase(Case, Config) -> + runner:init_per_testcase(?MODULE, Case, Config). + %% Tests formatting various atoms. atoms(Config) when is_list(Config) -> - P = runner:start(?atoms), + P = runner:start(Config, ?atoms), {term, ''} = get_term(P), {term, 'a'} = get_term(P), @@ -84,7 +88,7 @@ atoms(Config) when is_list(Config) -> %% Tests formatting various tuples tuples(Config) when is_list(Config) -> - P = runner:start(?tuples), + P = runner:start(Config, ?tuples), {term, {}} = get_term(P), {term, {a}} = get_term(P), @@ -105,7 +109,7 @@ tuples(Config) when is_list(Config) -> %% Tests formatting various lists lists(Config) when is_list(Config) -> - P = runner:start(?lists), + P = runner:start(Config, ?lists), {term, []} = get_term(P), {term, [a]} = get_term(P), @@ -146,7 +150,7 @@ lists(Config) when is_list(Config) -> format_wo_ver(Config) when is_list(Config) -> - P = runner:start(?format_wo_ver), + P = runner:start(Config, ?format_wo_ver), {term, [-1, 2, $c, {a, "b"}, {c, 10}]} = get_term(P), diff --git a/lib/erl_interface/test/ei_print_SUITE.erl b/lib/erl_interface/test/ei_print_SUITE.erl index 6d5c341eae..cad2686018 100644 --- a/lib/erl_interface/test/ei_print_SUITE.erl +++ b/lib/erl_interface/test/ei_print_SUITE.erl @@ -25,6 +25,7 @@ -include("ei_print_SUITE_data/ei_print_test_cases.hrl"). -export([all/0, suite/0, + init_per_testcase/2, atoms/1, tuples/1, lists/1, strings/1]). -import(runner, [get_term/1]). @@ -38,10 +39,13 @@ suite() -> all() -> [atoms, tuples, lists, strings]. +init_per_testcase(Case, Config) -> + runner:init_per_testcase(?MODULE, Case, Config). + %% Tests formatting various atoms. atoms(Config) when is_list(Config) -> - P = runner:start(?atoms), + P = runner:start(Config, ?atoms), {term, "''"} = get_term(P), {term, "a"} = get_term(P), @@ -79,7 +83,7 @@ atoms(Config) when is_list(Config) -> %% Tests formatting various tuples tuples(Config) when is_list(Config) -> - P = runner:start(?tuples), + P = runner:start(Config, ?tuples), {term, "{}"} = get_term(P), {term, "{a}"} = get_term(P), @@ -100,7 +104,7 @@ tuples(Config) when is_list(Config) -> %% Tests formatting various lists lists(Config) when is_list(Config) -> - P = runner:start(?lists), + P = runner:start(Config, ?lists), {term, "[]"} = get_term(P), {term, "[a]"} = get_term(P), @@ -125,7 +129,7 @@ lists(Config) when is_list(Config) -> ok. strings(Config) when is_list(Config) -> - P = runner:start(?strings), + P = runner:start(Config, ?strings), {term, "\"\\n\""} = get_term(P), {term, "\"\\r\\n\""} = get_term(P), diff --git a/lib/erl_interface/test/ei_tmo_SUITE.erl b/lib/erl_interface/test/ei_tmo_SUITE.erl index 003fe20594..1e76a99e1e 100644 --- a/lib/erl_interface/test/ei_tmo_SUITE.erl +++ b/lib/erl_interface/test/ei_tmo_SUITE.erl @@ -39,14 +39,16 @@ all() -> [framework_check, ei_accept_tmo, ei_connect_tmo, ei_send_tmo, ei_recv_tmo]. -init_per_testcase(_Case, Config) -> +init_per_testcase(Case, Config) -> + Config1 = runner:init_per_testcase(?MODULE, Case, Config), + % test if platform is vxworks_simso {_,Host} = split(node()), Bool = case atom_to_list(Host) of [$v,$x,$s,$i,$m | _] -> true; _ -> false end, - [{vxsim,Bool}|Config]. + [{vxsim,Bool} | Config1]. end_per_testcase(_Case, _Config) -> ok. @@ -55,7 +57,7 @@ end_per_testcase(_Case, _Config) -> framework_check(Config) when is_list(Config) -> %%dbg:tracer(), %%dbg:p(self()), - P = runner:start(?framework_check), + P = runner:start(Config, ?framework_check), runner:send_term(P,{hello,world}), {term, {hello,world}} = runner:get_term(P), runner:recv_eot(P), @@ -71,7 +73,7 @@ ei_recv_tmo(Config) when is_list(Config) -> do_one_recv(Config,CNode) -> {_,Host} = split(node()), - P1 = runner:start(?recv_tmo), + P1 = runner:start(Config, ?recv_tmo), runner:send_term(P1,{CNode, erlang:get_cookie(), node()}), @@ -84,7 +86,7 @@ do_one_recv(Config,CNode) -> runner:recv_eot(P1). do_one_recv_failure(Config,CNode) -> - P1 = runner:start(?recv_tmo), + P1 = runner:start(Config, ?recv_tmo), runner:send_term(P1,{CNode, erlang:get_cookie(), node()}), @@ -110,7 +112,7 @@ ei_send_tmo(Config) when is_list(Config) -> do_one_send(Config,From,CNode) -> {_,Host} = split(node()), - P1 = runner:start(?send_tmo), + P1 = runner:start(Config, ?send_tmo), runner:send_term(P1,{CNode, erlang:get_cookie(), node()}), @@ -139,7 +141,7 @@ do_one_send_failure(Config,From,FakeName,CName,VxSim) -> exit(Else) end, EpmdSocket = register(OurName, LSocket, 1, 5), - P3 = runner:start(?send_tmo), + P3 = runner:start(Config, ?send_tmo), Cookie = kaksmula_som_ingen_bryr_sig_om, runner:send_term(P3,{CName, Cookie, @@ -202,7 +204,7 @@ ei_connect_tmo(Config) when is_list(Config) -> %dbg:p(self()), VxSim = proplists:get_value(vxsim, Config), DummyNode = make_and_check_dummy(), - P = runner:start(?connect_tmo), + P = runner:start(Config, ?connect_tmo), runner:send_term(P,{c_nod_connect_tmo_1, kaksmula_som_ingen_bryr_sig_om, DummyNode}), @@ -219,7 +221,7 @@ ei_connect_tmo(Config) when is_list(Config) -> end end, runner:recv_eot(P), - P2 = runner:start(?connect_tmo), + P2 = runner:start(Config, ?connect_tmo), runner:send_term(P2,{c_nod_connect_tmo_2, erlang:get_cookie(), node()}), @@ -237,7 +239,7 @@ ei_connect_tmo(Config) when is_list(Config) -> exit(Else) end, EpmdSocket = register(OurName, LSocket, 1, 5), - P3 = runner:start(?connect_tmo), + P3 = runner:start(Config, ?connect_tmo), Cookie = kaksmula_som_ingen_bryr_sig_om, runner:send_term(P3,{c_nod_connect_tmo_3, Cookie, @@ -266,12 +268,12 @@ ei_connect_tmo(Config) when is_list(Config) -> ei_accept_tmo(Config) when is_list(Config) -> %%dbg:tracer(), %%dbg:p(self()), - P = runner:start(?accept_tmo), + P = runner:start(Config, ?accept_tmo), runner:send_term(P,{c_nod_som_ingen_kontaktar_1, kaksmula_som_ingen_bryr_sig_om}), {term,{-1,ETimedout,ETimedout}} = runner:get_term(P, 10000), runner:recv_eot(P), - P2 = runner:start(?accept_tmo), + P2 = runner:start(Config, ?accept_tmo), runner:send_term(P2,{c_nod_som_vi_kontaktar_1, erlang:get_cookie()}), receive after 1000 -> ok end, @@ -280,7 +282,7 @@ ei_accept_tmo(Config) when is_list(Config) -> {term, X} = runner:get_term(P2, 10000), runner:recv_eot(P2), true = is_integer(X), - P3 = runner:start(?accept_tmo), + P3 = runner:start(Config, ?accept_tmo), runner:send_term(P3,{c_nod_som_vi_kontaktar_2, erlang:get_cookie()}), receive after 1000 -> ok end, diff --git a/lib/erl_interface/test/erl_connect_SUITE.erl b/lib/erl_interface/test/erl_connect_SUITE.erl index cd73f07b8f..ad4e34c548 100644 --- a/lib/erl_interface/test/erl_connect_SUITE.erl +++ b/lib/erl_interface/test/erl_connect_SUITE.erl @@ -25,6 +25,7 @@ -include("erl_connect_SUITE_data/erl_connect_test_cases.hrl"). -export([all/0, suite/0, + init_per_testcase/2, erl_send/1, erl_reg_send/1, erl_send_cookie_file/1]). @@ -38,8 +39,11 @@ all() -> [erl_send, erl_reg_send, erl_send_cookie_file]. +init_per_testcase(Case, Config) -> + runner:init_per_testcase(?MODULE, Case, Config). + erl_send(Config) when is_list(Config) -> - P = runner:start(?interpret), + P = runner:start(Config, ?interpret), 1 = erl_connect_init(P, 42, erlang:get_cookie(), 0), {ok,Fd} = erl_connect(P, node()), @@ -56,7 +60,7 @@ erl_send_cookie_file(Config) when is_list(Config) -> vxworks -> {skip,"Skipped on VxWorks"}; _ -> - P = runner:start(?interpret), + P = runner:start(Config, ?interpret), 1 = erl_connect_init(P, 42, '', 0), {ok,Fd} = erl_connect(P, node()), @@ -70,7 +74,7 @@ erl_send_cookie_file(Config) when is_list(Config) -> end. erl_reg_send(Config) when is_list(Config) -> - P = runner:start(?interpret), + P = runner:start(Config, ?interpret), 1 = erl_connect_init(P, 42, erlang:get_cookie(), 0), {ok,Fd} = erl_connect(P, node()), diff --git a/lib/erl_interface/test/erl_eterm_SUITE.erl b/lib/erl_interface/test/erl_eterm_SUITE.erl index 3d1e33081b..84b58fed54 100644 --- a/lib/erl_interface/test/erl_eterm_SUITE.erl +++ b/lib/erl_interface/test/erl_eterm_SUITE.erl @@ -35,6 +35,7 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -export([all/0, suite/0, + init_per_testcase/2, build_terms/1, round_trip_conversion/1, decode_terms/1, decode_float/1, t_erl_mk_int/1, t_erl_mk_list/1, @@ -94,6 +95,9 @@ all() -> high_chaparal, broken_data, cnode_1]. +init_per_testcase(Case, Config) -> + runner:init_per_testcase(?MODULE, Case, Config). + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% %%% 1. B a s i c t e s t s @@ -104,7 +108,7 @@ all() -> %% a list and verifies that the result is as expected. build_terms(Config) when is_list(Config) -> - P = runner:start(?build_terms), + P = runner:start(Config, ?build_terms), {term, Term} = get_term(P), io:format("Received: ~p", [Term]), [ARefLN, ARef, APortLN, APort, APidLN, APid, @@ -136,7 +140,7 @@ build_terms(Config) when is_list(Config) -> %% This test is run entirely in C code. round_trip_conversion(Config) when is_list(Config) -> - runner:test(?round_trip_conversion), + runner:test(Config, ?round_trip_conversion), ok. %% This test sends a list of all data types to the C code function, @@ -156,7 +160,7 @@ decode_terms(Config) when is_list(Config) -> {element1, 42, 767}, "A string", 1, -1, 0, 3.0, ABinary, 'I am an atom'], - P = runner:start(?decode_terms), + P = runner:start(Config, ?decode_terms), runner:send_term(P, Terms), runner:recv_eot(P), @@ -165,7 +169,7 @@ decode_terms(Config) when is_list(Config) -> %% Decodes the floating point number 3.1415. decode_float(Config) when is_list(Config) -> - P = runner:start(?decode_float), + P = runner:start(Config, ?decode_float), runner:send_term(P, 3.1415), runner:recv_eot(P), ok. @@ -173,7 +177,7 @@ decode_float(Config) when is_list(Config) -> %% Tests the erl_free_compound() function. t_erl_free_compound(Config) when is_list(Config) -> - runner:test(?t_erl_free_compound), + runner:test(Config, ?t_erl_free_compound), ok. @@ -186,7 +190,7 @@ t_erl_free_compound(Config) when is_list(Config) -> %% This tests the erl_mk_list() function. t_erl_mk_list(Config) when is_list(Config) -> - P = runner:start(?t_erl_mk_list), + P = runner:start(Config, ?t_erl_mk_list), {term, []} = get_term(P), {term, [abc]} = get_term(P), @@ -200,7 +204,7 @@ t_erl_mk_list(Config) when is_list(Config) -> %% This tests the erl_mk_int() function. t_erl_mk_int(Config) when is_list(Config) -> - P = runner:start(?t_erl_mk_int), + P = runner:start(Config, ?t_erl_mk_int), {term, 0} = get_term(P), {term, 127} = get_term(P), @@ -255,14 +259,14 @@ t_erl_mk_int(Config) when is_list(Config) -> %% Basic test of erl_copy_term(). basic_copy(Config) when is_list(Config) -> - runner:test(?basic_copy), + runner:test(Config, ?basic_copy), ok. %% This tests the erl_mk_tuple() function. t_erl_mk_tuple(Config) when is_list(Config) -> - P = runner:start(?t_erl_mk_tuple), + P = runner:start(Config, ?t_erl_mk_tuple), {term, {madonna, 21, 'mad donna', 12}} = get_term(P), {term, {'Madonna',21,{children,{"Isabella",2}}, @@ -275,7 +279,7 @@ t_erl_mk_tuple(Config) when is_list(Config) -> %% This tests the erl_mk_atom() function. t_erl_mk_atom(Config) when is_list(Config) -> - P = runner:start(?t_erl_mk_atom), + P = runner:start(Config, ?t_erl_mk_atom), {term, madonna} = (get_term(P)), {term, 'Madonna'} = (get_term(P)), @@ -295,7 +299,7 @@ t_erl_mk_atom(Config) when is_list(Config) -> %% This tests the erl_mk_binary() function. t_erl_mk_binary(Config) when is_list(Config) -> - P = runner:start(?t_erl_mk_binary), + P = runner:start(Config, ?t_erl_mk_binary), {term, Bin} = (get_term(P)), "{madonna,21,'mad donna',1234.567.890, !#$%&/()=?+-@, \" \\}" = binary_to_list(Bin), @@ -307,7 +311,7 @@ t_erl_mk_binary(Config) when is_list(Config) -> %% This tests the erl_mk_empty_list() function. t_erl_mk_empty_list(Config) when is_list(Config) -> - P = runner:start(?t_erl_mk_empty_list), + P = runner:start(Config, ?t_erl_mk_empty_list), {term, []} = get_term(P), @@ -322,7 +326,7 @@ t_erl_mk_float(Config) when is_list(Config) -> vxworks -> {skipped, "Floating point numbers never compare equal on PPC"}; _ -> - P = runner:start(?t_erl_mk_float), + P = runner:start(Config, ?t_erl_mk_float), {term, {3.1415, 1.999999, 2.000000, 2.000001, 2.000002, 12345.67890}} = get_term(P), runner:recv_eot(P), @@ -333,7 +337,7 @@ t_erl_mk_float(Config) when is_list(Config) -> %% This tests the erl_mk_pid() function. t_erl_mk_pid(Config) when is_list(Config) -> - P = runner:start(?t_erl_mk_pid), + P = runner:start(Config, ?t_erl_mk_pid), {term, A_pid} = (get_term(P)), {pid, kalle@localhost, 3, 2} = nc2vinfo(A_pid), @@ -342,7 +346,7 @@ t_erl_mk_pid(Config) when is_list(Config) -> ok. t_erl_mk_xpid(Config) when is_list(Config) -> - P = runner:start(?t_erl_mk_xpid), + P = runner:start(Config, ?t_erl_mk_xpid), {term, A_pid} = (get_term(P)), {pid, kalle@localhost, 32767, 8191} = nc2vinfo(A_pid), @@ -354,7 +358,7 @@ t_erl_mk_xpid(Config) when is_list(Config) -> %% This tests the erl_mk_port() function. t_erl_mk_port(Config) when is_list(Config) -> - P = runner:start(?t_erl_mk_port), + P = runner:start(Config, ?t_erl_mk_port), {term, A_port} = (get_term(P)), {port, kalle@localhost, 4} = nc2vinfo(A_port), @@ -363,7 +367,7 @@ t_erl_mk_port(Config) when is_list(Config) -> ok. t_erl_mk_xport(Config) when is_list(Config) -> - P = runner:start(?t_erl_mk_xport), + P = runner:start(Config, ?t_erl_mk_xport), {term, A_port} = (get_term(P)), {port, kalle@localhost, 268435455} = nc2vinfo(A_port), @@ -375,7 +379,7 @@ t_erl_mk_xport(Config) when is_list(Config) -> %% This tests the erl_mk_ref() function. t_erl_mk_ref(Config) when is_list(Config) -> - P = runner:start(?t_erl_mk_ref), + P = runner:start(Config, ?t_erl_mk_ref), {term, A_ref} = (get_term(P)), {ref, kalle@localhost, _Length, [6]} = nc2vinfo(A_ref), @@ -384,7 +388,7 @@ t_erl_mk_ref(Config) when is_list(Config) -> ok. t_erl_mk_long_ref(Config) when is_list(Config) -> - P = runner:start(?t_erl_mk_long_ref), + P = runner:start(Config, ?t_erl_mk_long_ref), {term, A_ref} = (get_term(P)), {ref, kalle@localhost, _Length, [4294967295,4294967295,262143]} @@ -397,7 +401,7 @@ t_erl_mk_long_ref(Config) when is_list(Config) -> %% This tests the erl_mk_string() function. t_erl_mk_string(Config) when is_list(Config) -> - P = runner:start(?t_erl_mk_string), + P = runner:start(Config, ?t_erl_mk_string), {term, "madonna"} = (get_term(P)), {term, "Madonna"} = (get_term(P)), @@ -417,7 +421,7 @@ t_erl_mk_string(Config) when is_list(Config) -> %% This tests the erl_mk_estring() function. t_erl_mk_estring(Config) when is_list(Config) -> - P = runner:start(?t_erl_mk_estring), + P = runner:start(Config, ?t_erl_mk_estring), {term, "madonna"} = (get_term(P)), {term, "Madonna"} = (get_term(P)), @@ -437,7 +441,7 @@ t_erl_mk_estring(Config) when is_list(Config) -> %% This tests the erl_mk_uint() function. t_erl_mk_uint(Config) when is_list(Config) -> - P = runner:start(?t_erl_mk_uint), + P = runner:start(Config, ?t_erl_mk_uint), {term, 54321} = (get_term(P)), {term, 2147483647} = (get_term(P)), @@ -453,7 +457,7 @@ t_erl_mk_uint(Config) when is_list(Config) -> %% This tests the erl_mk_var() function. t_erl_mk_var(Config) when is_list(Config) -> - P = runner:start(?t_erl_mk_var), + P = runner:start(Config, ?t_erl_mk_var), {term, 1} = (get_term(P)), {term, 0} = (get_term(P)), @@ -470,7 +474,7 @@ t_erl_mk_var(Config) when is_list(Config) -> %% This tests the erl_cons() function. t_erl_cons(Config) when is_list(Config) -> - P = runner:start(?t_erl_cons), + P = runner:start(Config, ?t_erl_cons), {term, [madonna, 21]} = get_term(P), @@ -490,7 +494,7 @@ t_erl_cons(Config) when is_list(Config) -> %% Tests the erl_length() function. t_erl_length(Config) when is_list(Config) -> - P = runner:start(?t_erl_length), + P = runner:start(Config, ?t_erl_length), 0 = erl_length(P, []), 1 = erl_length(P, [a]), @@ -513,7 +517,7 @@ erl_length(Port, List) -> %% Tests the erl_hd() function. t_erl_hd(Config) when is_list(Config) -> - P = runner:start(?t_erl_hd), + P = runner:start(Config, ?t_erl_hd), 'NULL' = erl_hd(P, 42), 'NULL' = erl_hd(P, abc), @@ -537,7 +541,7 @@ erl_hd(Port, List) -> %% Tests the erl_tail() function. t_erl_tl(Config) when is_list(Config) -> - P = runner:start(?t_erl_tl), + P = runner:start(Config, ?t_erl_tl), 'NULL' = erl_tl(P, 42), 'NULL' = erl_tl(P, abc), @@ -561,20 +565,20 @@ erl_tl(Port, List) -> %% Tests the type checking macros (done in the C program). type_checks(Config) when is_list(Config) -> - runner:test(?type_checks), + runner:test(Config, ?type_checks), ok. %% Tests the extractor macros (done in the C program). extractor_macros(Config) when is_list(Config) -> - runner:test(?extractor_macros), + runner:test(Config, ?extractor_macros), ok. %% This tests the erl_size() function. t_erl_size(Config) when is_list(Config) -> - P = runner:start(?t_erl_size), + P = runner:start(Config, ?t_erl_size), {term, 0} = (get_term(P)), {term, 4} = (get_term(P)), @@ -589,7 +593,7 @@ t_erl_size(Config) when is_list(Config) -> %% This tests the erl_var_content() function. t_erl_var_content(Config) when is_list(Config) -> - P = runner:start(?t_erl_var_content), + P = runner:start(Config, ?t_erl_var_content), {term, 17} = (get_term(P)), {term, "http://www.madonna.com"} = (get_term(P)), @@ -604,7 +608,7 @@ t_erl_var_content(Config) when is_list(Config) -> %% This tests the erl_element() function. t_erl_element(Config) when is_list(Config) -> - P = runner:start(?t_erl_element), + P = runner:start(Config, ?t_erl_element), {term, madonna} = get_term(P), {term, 21} = get_term(P), @@ -630,7 +634,7 @@ t_erl_element(Config) when is_list(Config) -> %% Tests the erl_iolist_length() function. t_erl_iolist_length(Config) when is_list(Config) -> - P = runner:start(?t_erl_iolist_length), + P = runner:start(Config, ?t_erl_iolist_length), %% Flat lists. @@ -697,7 +701,7 @@ erl_iolist_length(Port, List) -> %% Tests the erl_iolist_to_binary() function. t_erl_iolist_to_binary(Config) when is_list(Config) -> - P = runner:start(?t_erl_iolist_to_binary), + P = runner:start(Config, ?t_erl_iolist_to_binary), %% Flat lists. @@ -768,7 +772,7 @@ iolist_to_list(Port, Term) -> %% Tests the erl_iolist_to_string() function. t_erl_iolist_to_string(Config) when is_list(Config) -> - P = runner:start(?t_erl_iolist_to_string), + P = runner:start(Config, ?t_erl_iolist_to_string), %% Flat lists. @@ -947,14 +951,14 @@ collect_line1([C|Rest], Result) -> %% Test case submitted by Per Lundgren, ERV. high_chaparal(Config) when is_list(Config) -> - P = runner:start(?high_chaparal), + P = runner:start(Config, ?high_chaparal), {term, [hello, world]} = get_term(P), runner:recv_eot(P), ok. %% OTP-7448 broken_data(Config) when is_list(Config) -> - P = runner:start(?broken_data), + P = runner:start(Config, ?broken_data), runner:recv_eot(P), ok. diff --git a/lib/erl_interface/test/erl_ext_SUITE.erl b/lib/erl_interface/test/erl_ext_SUITE.erl index afaba1fd93..806339b122 100644 --- a/lib/erl_interface/test/erl_ext_SUITE.erl +++ b/lib/erl_interface/test/erl_ext_SUITE.erl @@ -25,6 +25,7 @@ -include("erl_ext_SUITE_data/ext_test_cases.hrl"). -export([all/0, suite/0, + init_per_testcase/2, compare_tuple/1, compare_list/1, compare_string/1, @@ -40,28 +41,30 @@ all() -> [compare_tuple, compare_list, compare_string, compare_list_string, compare_nc_ext]. +init_per_testcase(Case, Config) -> + runner:init_per_testcase(?MODULE, Case, Config). compare_tuple(Config) when is_list(Config) -> - P = runner:start(?compare_tuple), + P = runner:start(Config, ?compare_tuple), runner:recv_eot(P), ok. compare_list(Config) when is_list(Config) -> - P = runner:start(?compare_list), + P = runner:start(Config, ?compare_list), runner:recv_eot(P), ok. compare_string(Config) when is_list(Config) -> - P = runner:start(?compare_string), + P = runner:start(Config, ?compare_string), runner:recv_eot(P), ok. compare_list_string(Config) when is_list(Config) -> - P = runner:start(?compare_list_string), + P = runner:start(Config, ?compare_list_string), runner:recv_eot(P), ok. compare_nc_ext(Config) when is_list(Config) -> - P = runner:start(?compare_nc_ext), + P = runner:start(Config, ?compare_nc_ext), runner:recv_eot(P), ok. diff --git a/lib/erl_interface/test/erl_format_SUITE.erl b/lib/erl_interface/test/erl_format_SUITE.erl index c1a7d8377e..d984dcb08e 100644 --- a/lib/erl_interface/test/erl_format_SUITE.erl +++ b/lib/erl_interface/test/erl_format_SUITE.erl @@ -25,6 +25,7 @@ -include("erl_format_SUITE_data/format_test_cases.hrl"). -export([all/0, suite/0, + init_per_testcase/2, atoms/1, tuples/1, lists/1]). -import(runner, [get_term/1]). @@ -38,10 +39,13 @@ suite() -> all() -> [atoms, tuples, lists]. +init_per_testcase(Case, Config) -> + runner:init_per_testcase(?MODULE, Case, Config). + %% Tests formatting various atoms. atoms(Config) when is_list(Config) -> - P = runner:start(?atoms), + P = runner:start(Config, ?atoms), {term, ''} = get_term(P), {term, 'a'} = get_term(P), @@ -79,7 +83,7 @@ atoms(Config) when is_list(Config) -> %% Tests formatting various tuples tuples(Config) when is_list(Config) -> - P = runner:start(?tuples), + P = runner:start(Config, ?tuples), {term, {}} = get_term(P), {term, {a}} = get_term(P), @@ -100,7 +104,7 @@ tuples(Config) when is_list(Config) -> %% Tests formatting various lists lists(Config) when is_list(Config) -> - P = runner:start(?lists), + P = runner:start(Config, ?lists), {term, []} = get_term(P), {term, [a]} = get_term(P), diff --git a/lib/erl_interface/test/erl_global_SUITE.erl b/lib/erl_interface/test/erl_global_SUITE.erl index ecc6753c7f..560afd58ba 100644 --- a/lib/erl_interface/test/erl_global_SUITE.erl +++ b/lib/erl_interface/test/erl_global_SUITE.erl @@ -25,6 +25,7 @@ -include("erl_global_SUITE_data/erl_global_test_cases.hrl"). -export([all/0,suite/0, + init_per_testcase/2, erl_global_registration/1, erl_global_whereis/1, erl_global_names/1]). @@ -39,9 +40,11 @@ suite() -> [{ct_hooks,[ts_install_cth]}, {timetrap, {seconds, 30}}]. +init_per_testcase(Case, Config) -> + runner:init_per_testcase(?MODULE, Case, Config). erl_global_registration(Config) when is_list(Config) -> - P = runner:start(?interpret), + P = runner:start(Config, ?interpret), {ok, Fd} = erl_connect(P, node(), 42, erlang:get_cookie(), 0), ok = erl_global_register(P, Fd, ?GLOBAL_NAME), @@ -53,7 +56,7 @@ erl_global_registration(Config) when is_list(Config) -> ok. erl_global_whereis(Config) when is_list(Config) -> - P = runner:start(?interpret), + P = runner:start(Config, ?interpret), {ok, Fd} = erl_connect(P, node(), 42, erlang:get_cookie(), 0), Self = self(), @@ -66,7 +69,7 @@ erl_global_whereis(Config) when is_list(Config) -> ok. erl_global_names(Config) when is_list(Config) -> - P = runner:start(?interpret), + P = runner:start(Config, ?interpret), {ok, Fd} = erl_connect(P, node(), 42, erlang:get_cookie(), 0), Self = self(), diff --git a/lib/erl_interface/test/erl_match_SUITE.erl b/lib/erl_interface/test/erl_match_SUITE.erl index 5566714092..f1f6892ae0 100644 --- a/lib/erl_interface/test/erl_match_SUITE.erl +++ b/lib/erl_interface/test/erl_match_SUITE.erl @@ -25,6 +25,7 @@ -include("erl_match_SUITE_data/match_test_cases.hrl"). -export([all/0, suite/0, + init_per_testcase/2, atoms/1, lists/1, tuples/1, references/1, pids/1, ports/1, bind/1, integers/1, floats/1, binaries/1, strings/1]). @@ -40,6 +41,8 @@ all() -> [atoms, lists, tuples, references, pids, ports, bind, integers, floats, binaries, strings]. +init_per_testcase(Case, Config) -> + runner:init_per_testcase(?MODULE, Case, Config). atoms(Config) when is_list(Config) -> P = start_matcher(Config), @@ -239,7 +242,7 @@ bind(Config) when is_list(Config) -> ok. start_bind(Config) -> - runner:start(?erl_match_bind). + runner:start(Config, ?erl_match_bind). bind_ok(Port, Bind, Term) -> true = erl_bind(Port, Bind, Term). @@ -258,7 +261,7 @@ erl_bind(Port, Pattern, Term) -> start_matcher(Config) -> - runner:start(?erl_match_server). + runner:start(Config, ?erl_match_server). eq(Port, Pattern, Term) -> true = erl_match(Port, Pattern, Term). diff --git a/lib/erl_interface/test/port_call_SUITE.erl b/lib/erl_interface/test/port_call_SUITE.erl index fb10bd895f..d31b2372ab 100644 --- a/lib/erl_interface/test/port_call_SUITE.erl +++ b/lib/erl_interface/test/port_call_SUITE.erl @@ -32,7 +32,9 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --export([all/0, suite/0, basic/1]). +-export([all/0, suite/0, + init_per_testcase/2, + basic/1]). % Private exports -include_lib("common_test/include/ct.hrl"). @@ -44,6 +46,8 @@ suite() -> all() -> [basic]. +init_per_testcase(Case, Config) -> + runner:init_per_testcase(?MODULE, Case, Config). basic(Config) when is_list(Config) -> case os:type() of diff --git a/lib/erl_interface/test/runner.erl b/lib/erl_interface/test/runner.erl index 947e56c4e0..484890006e 100644 --- a/lib/erl_interface/test/runner.erl +++ b/lib/erl_interface/test/runner.erl @@ -21,8 +21,9 @@ %% -module(runner). --export([test/1, test/2, - start/1, send_term/2, finish/1, send_eot/1, recv_eot/1, +-export([test/2, test/3, + init_per_testcase/3, + start/2, send_term/2, finish/1, send_eot/1, recv_eot/1, get_term/1, get_term/2]). -define(default_timeout, 5000). @@ -32,11 +33,11 @@ %% This function is useful for test cases written in C which requires %% no further input, and only returns a result by calling report(). -test(Tc) -> - test(Tc, ?default_timeout). +test(Config, Tc) -> + test(Config, Tc, ?default_timeout). -test(Tc, Timeout) -> - Port = start(Tc), +test(Config, Tc, Timeout) -> + Port = start(Config, Tc), case get_term(Port, Timeout) of eot -> @@ -54,12 +55,51 @@ test(Tc, Timeout) -> %% %% Returns: {ok, Port} -start({Prog, Tc}) when is_list(Prog), is_integer(Tc) -> - Port = open_port({spawn, Prog}, [{packet, 4}, exit_status]), +start(Config, {Prog, Tc}) when is_list(Prog), is_integer(Tc) -> + Port = open_port({spawn, prog_cmd(Config, Prog)}, + [{packet, 4}, exit_status]), Command = [Tc div 256, Tc rem 256], Port ! {self(), {command, Command}}, Port. +prog_cmd(Config, Prog) -> + case proplists:get_value(valgrind_cmd_fun, Config) of + undefined -> + Prog; + Fun when is_function(Fun) -> + Fun(Prog) + end. + +init_per_testcase(Suite, Case, Config) -> + case os:getenv("VALGRIND_LOG_DIR") of + false -> + Config; + LogDir -> + Valgrind = case os:find_executable("valgrind") of + false -> + ct:fail("VALGRIND_LOG_DIR set, " + "but no valgrind executable found"); + VG -> VG + end, + + LogFileOpt = case os:getenv("VALGRIND_LOG_XML") of + false -> + " --log-file="; + "yes" -> + " --xml=yes --xml-file=" + end, + Fun = fun(Prog) -> + LogFile = io_lib:format("erl_interface-~w.~w-~s.log.%p", + [Suite, Case, filename:basename(Prog)]), + Valgrind + ++ LogFileOpt ++ filename:join(LogDir,LogFile) + ++ " " ++ os:getenv("VALGRIND_MISC_FLAGS","") + ++ " " ++ Prog + end, + [{valgrind_cmd_fun, Fun} | Config] + end. + + %% Finishes a test case by send an 'eot' message to the C program %% and waiting for an 'eot'. %% diff --git a/lib/et/doc/src/Makefile b/lib/et/doc/src/Makefile index 4758559220..93e2f8eeee 100644 --- a/lib/et/doc/src/Makefile +++ b/lib/et/doc/src/Makefile @@ -85,6 +85,7 @@ clean clean_docs: fi \ done rm -rf $(HTMLDIR)/* + rm -rf $(XMLDIR) rm -f $(MAN3DIR)/* rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo) rm -f errs core *~ diff --git a/lib/eunit/doc/src/Makefile b/lib/eunit/doc/src/Makefile index e91d947592..117542cb37 100644 --- a/lib/eunit/doc/src/Makefile +++ b/lib/eunit/doc/src/Makefile @@ -146,6 +146,7 @@ debug opt: clean clean_docs: rm -rf $(HTMLDIR)/* + rm -rf $(XMLDIR) rm -f $(MAN3DIR)/* rm -f $(XML_REF3_FILES) $(XML_CHAPTER_FILES) *.html rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo) diff --git a/lib/ftp/doc/src/Makefile b/lib/ftp/doc/src/Makefile index e96a9c032f..20fbbc73a9 100644 --- a/lib/ftp/doc/src/Makefile +++ b/lib/ftp/doc/src/Makefile @@ -103,6 +103,7 @@ pdf: $(TOP_PDF_FILE) html: gifs $(HTML_REF_MAN_FILE) clean clean_docs: clean_html clean_man clean_pdf + rm -rf $(XMLDIR) rm -f errs core *~ man: $(MAN3_FILES) diff --git a/lib/hipe/doc/src/Makefile b/lib/hipe/doc/src/Makefile index 1c774d3357..bd6a7b2f74 100644 --- a/lib/hipe/doc/src/Makefile +++ b/lib/hipe/doc/src/Makefile @@ -94,6 +94,7 @@ debug opt: clean clean_docs: rm -rf $(HTMLDIR)/* + rm -rf $(XMLDIR) rm -f $(MAN3DIR)/* rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo) rm -f errs core *~ diff --git a/lib/inets/doc/src/Makefile b/lib/inets/doc/src/Makefile index 29b8678cda..cbc0e384d8 100644 --- a/lib/inets/doc/src/Makefile +++ b/lib/inets/doc/src/Makefile @@ -115,6 +115,7 @@ pdf: $(TOP_PDF_FILE) html: gifs $(HTML_REF_MAN_FILE) clean clean_docs: clean_html clean_man clean_pdf + rm -rf $(XMLDIR) rm -f errs core *~ man: $(MAN3_FILES) diff --git a/lib/inets/doc/src/notes.xml b/lib/inets/doc/src/notes.xml index d967f56576..fadfdd500f 100644 --- a/lib/inets/doc/src/notes.xml +++ b/lib/inets/doc/src/notes.xml @@ -92,6 +92,21 @@ </section> +<section><title>Inets 6.5.2.2</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Enhance error handling, that is mod_get will return 403 + if a path is a directory and not a file.</p> + <p> + Own Id: OTP-15192</p> + </item> + </list> + </section> + +</section> <section><title>Inets 6.5.2.1</title> diff --git a/lib/inets/src/http_server/httpd_file.erl b/lib/inets/src/http_server/httpd_file.erl index 4d419172d0..fb71834e95 100644 --- a/lib/inets/src/http_server/httpd_file.erl +++ b/lib/inets/src/http_server/httpd_file.erl @@ -33,6 +33,9 @@ handle_error(enoent, Op, ModData, Path) -> handle_error(enotdir, Op, ModData, Path) -> handle_error(404, Op, ModData, Path, ": A component of the file name is not a directory"); +handle_error(eisdir, Op, ModData, Path) -> + handle_error(403, Op, ModData, Path, + ":Ilegal operation expected a file not a directory"); handle_error(emfile, Op, _ModData, Path) -> handle_error(500, Op, none, Path, ": Too many open files"); handle_error({enfile,_}, Op, _ModData, Path) -> diff --git a/lib/inets/test/httpd_SUITE.erl b/lib/inets/test/httpd_SUITE.erl index 97aca73d6b..dc4f607750 100644 --- a/lib/inets/test/httpd_SUITE.erl +++ b/lib/inets/test/httpd_SUITE.erl @@ -448,8 +448,19 @@ get(Config) when is_list(Config) -> {header, "Content-Type", "text/html"}, {header, "Date"}, {header, "Server"}, + {version, Version}]), + + ok = httpd_test_lib:verify_request(proplists:get_value(type, Config), Host, + proplists:get_value(port, Config), + transport_opts(Type, Config), + proplists:get_value(node, Config), + http_request("GET /open/ ", Version, Host), + [{statuscode, 403}, + {header, "Content-Type", "text/html"}, + {header, "Date"}, + {header, "Server"}, {version, Version}]). - + basic_auth_1_1(Config) when is_list(Config) -> basic_auth([{http_version, "HTTP/1.1"} | Config]). @@ -1992,7 +2003,7 @@ head_status(_) -> basic_conf() -> [{modules, [mod_alias, mod_range, mod_responsecontrol, - mod_trace, mod_esi, mod_cgi, mod_dir, mod_get, mod_head]}]. + mod_trace, mod_esi, mod_cgi, mod_get, mod_head]}]. auth_access_conf() -> [{modules, [mod_alias, mod_htaccess, mod_dir, mod_get, mod_head]}, diff --git a/lib/jinterface/doc/src/Makefile b/lib/jinterface/doc/src/Makefile index 37de0a35c5..6f1ecc8dea 100644 --- a/lib/jinterface/doc/src/Makefile +++ b/lib/jinterface/doc/src/Makefile @@ -129,6 +129,7 @@ html: gifs $(HTML_REF_MAN_FILE) clean clean_docs: rm -rf $(HTMLDIR)/* + rm -rf $(XMLDIR) rm -f $(MAN3DIR)/* rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo) rm -f errs core *~ diff --git a/lib/kernel/doc/src/.gitignore b/lib/kernel/doc/src/.gitignore new file mode 100644 index 0000000000..c2813ac866 --- /dev/null +++ b/lib/kernel/doc/src/.gitignore @@ -0,0 +1 @@ +*.eps
\ No newline at end of file diff --git a/lib/kernel/doc/src/Makefile b/lib/kernel/doc/src/Makefile index f34eee71ba..f8867ccf25 100644 --- a/lib/kernel/doc/src/Makefile +++ b/lib/kernel/doc/src/Makefile @@ -84,6 +84,7 @@ XML_CHAPTER_FILES = \ BOOK_FILES = book.xml +# The .png file is generated from a .dia file with target 'update_png' IMAGE_FILES = \ logger_arch.png @@ -112,6 +113,17 @@ SPECS_FILES = $(XML_REF3_FILES:%.xml=$(SPECDIR)/specs_%.xml) TOP_SPECS_FILE = specs.xml # ---------------------------------------------------- +# FIGURES +# ---------------------------------------------------- +# In order to update the figures you have to have both dia +# and imagemagick installed. +# The generated .png file must be committed. + +update_png: + dia --export=logger_arch.eps logger_arch.dia + convert logger_arch.eps -resize 65% logger_arch.png + +# ---------------------------------------------------- # FLAGS # ---------------------------------------------------- XML_FLAGS += @@ -142,12 +154,13 @@ debug opt: clean clean_docs: rm -rf $(HTMLDIR)/* + rm -rf $(XMLDIR) rm -f $(MAN3DIR)/* rm -f $(MAN4DIR)/* rm -f $(MAN6DIR)/* rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo) rm -f $(SPECDIR)/* - rm -f errs core *~ + rm -f errs core *~ *.eps $(SPECDIR)/specs_erl_prim_loader_stub.xml: $(gen_verbose)escript $(SPECS_EXTRACTOR) $(SPECS_FLAGS) \ diff --git a/lib/kernel/doc/src/kernel_app.xml b/lib/kernel/doc/src/kernel_app.xml index 3914226a3e..ccb7d17d25 100644 --- a/lib/kernel/doc/src/kernel_app.xml +++ b/lib/kernel/doc/src/kernel_app.xml @@ -310,24 +310,31 @@ <tag><c>net_ticktime = TickTime</c></tag> <item> <marker id="net_ticktime"></marker> - <p>Specifies the <c>net_kernel</c> tick time. <c>TickTime</c> - is specified in seconds. Once every <c>TickTime/4</c> second, all - connected nodes are ticked (if anything else is written - to a node). If nothing is received from another node - within the last four tick times, that node is considered - to be down. This ensures that nodes that are not responding, - for reasons such as hardware errors, are considered to be - down.</p> - <p>The time <c>T</c>, in which a node that is not responding is - detected, is calculated as <c><![CDATA[MinT < T < MaxT]]></c>, where:</p> + <p>Specifies the <c>net_kernel</c> tick time in seconds. This is the + approximate time a connected node may be unresponsive until it is + considered down and thereby disconnected.</p> + <p>Once every <c>TickTime/4</c> seconds, each connected node is ticked + if nothing has been sent to it during that last <c>TickTime/4</c> + interval. A tick is a small package sent on the connection. A connected + node is considered to be down if no ticks or payload packages have been + received during the last four <c>TickTime/4</c> intervals. This ensures + that nodes that are not responding, for reasons such as hardware errors, + are considered to be down.</p> + <p>As the availability is only checked every <c>TickTime/4</c> seconds, + the actual time <c>T</c> a node have been unresponsive when + detected may vary between <c>MinT</c> and <c>MaxT</c>, + where:</p> <code type="none"> MinT = TickTime - TickTime / 4 MaxT = TickTime + TickTime / 4</code> - <p><c>TickTime</c> defaults to <c>60</c> (seconds). Thus, - <c><![CDATA[45 < T < 75]]></c> seconds.</p> - <p>Notice that <em>all</em> communicating nodes are to have the <em>same</em> - <c>TickTime</c> value specified.</p> - <p>Normally, a terminating node is detected immediately.</p> + <p><c>TickTime</c> defaults to <c>60</c> seconds. Thus, + <c><![CDATA[45 < T < 75]]></c> seconds.</p> + <p>Notice that <em>all</em> communicating nodes are to have the + <em>same</em> <c>TickTime</c> value specified, as it determines both the + frequency of outgoing ticks and the expected frequency of incominging + ticks.</p> + <p>Normally, a terminating node is detected immediately by the transport + protocol (like TCP/IP).</p> </item> <tag><c>shutdown_timeout = integer() | infinity</c></tag> <item> diff --git a/lib/kernel/doc/src/logger.xml b/lib/kernel/doc/src/logger.xml index 33f1919de0..f1830a8224 100644 --- a/lib/kernel/doc/src/logger.xml +++ b/lib/kernel/doc/src/logger.xml @@ -98,46 +98,6 @@ logger:error("error happened because: ~p", [Reason]). % Without macro <datatypes> <datatype> - <name name="primary_config"/> - <desc> - <p>Primary configuration data for Logger. The following - default values apply:</p> - <list> - <item><c>level => info</c></item> - <item><c>filter_default => log</c></item> - <item><c>filters => []</c></item> - </list> - </desc> - </datatype> - <datatype> - <name name="handler_config"/> - <desc> - <p>Handler configuration data for Logger. The following - default values apply:</p> - <list> - <item><c>level => all</c></item> - <item><c>filter_default => log</c></item> - <item><c>filters => []</c></item> - <item><c>formatter => {logger_formatter, DefaultFormatterConfig</c>}</item> - </list> - <p>In addition to these, the following fields are - automatically inserted by Logger, values taken from the - two first parameters - to <seealso marker="#add_handler-3"><c>add_handler/3</c></seealso>:</p> - <list> - <item><c>id => HandlerId</c></item> - <item><c>module => Module</c></item> - </list> - <p>Handler specific configuration data is inserted by the - handler callback itself, in a sub structure associated with - the field named <c>config</c>.</p> - <p>See the <seealso marker="logger_formatter#type-config"> - <c>logger_formatter(3)</c></seealso> manual page for - information about the default configuration for this - formatter.</p> - </desc> - </datatype> - <datatype> <name name="filter"/> <desc> <p>A filter which can be installed as a handler filter, or as @@ -172,6 +132,39 @@ logger:error("error happened because: ~p", [Reason]). % Without macro </desc> </datatype> <datatype> + <name name="handler_config"/> + <desc> + <p>Handler configuration data for Logger. The following + default values apply:</p> + <list> + <item><c>level => all</c></item> + <item><c>filter_default => log</c></item> + <item><c>filters => []</c></item> + <item><c>formatter => {logger_formatter, DefaultFormatterConfig</c>}</item> + </list> + <p>In addition to these, the following fields are + automatically inserted by Logger, values taken from the + two first parameters + to <seealso marker="#add_handler-3"><c>add_handler/3</c></seealso>:</p> + <list> + <item><c>id => HandlerId</c></item> + <item><c>module => Module</c></item> + </list> + <p>These are read-only and cannot be changed in runtime.</p> + <p>Handler specific configuration data is inserted by the + handler callback itself, in a sub structure associated with + the field named <c>config</c>. See + the <seealso marker="logger_std_h"><c>logger_std_h(3)</c></seealso> + and <seealso marker="logger_disk_log_h"><c>logger_disk_log_h</c></seealso> + manual pages for information about the specifc configuration + for these handlers.</p> + <p>See the <seealso marker="logger_formatter#type-config"> + <c>logger_formatter(3)</c></seealso> manual page for + information about the default configuration for this + formatter.</p> + </desc> + </datatype> + <datatype> <name name="handler_id"/> <desc> <p>A unique identifier for a handler instance.</p> @@ -234,7 +227,10 @@ logger:error("error happened because: ~p", [Reason]). % Without macro a <seealso marker="#type-report"><c>report()</c></seealso>, the <c>report_cb</c> key can be associated with a fun (report callback) that converts the report to a format - string and arguments. See + string and arguments, or directly to a string. See the + type definition + of <seealso marker="#type-report_cb"><c>report_cb()</c></seealso>, + and section <seealso marker="logger_chapter#log_message">Log Message</seealso> in the User's Guide for more information about report callbacks.</p> @@ -249,12 +245,40 @@ logger:error("error happened because: ~p", [Reason]). % Without macro </desc> </datatype> <datatype> + <name name="primary_config"/> + <desc> + <p>Primary configuration data for Logger. The following + default values apply:</p> + <list> + <item><c>level => info</c></item> + <item><c>filter_default => log</c></item> + <item><c>filters => []</c></item> + </list> + </desc> + </datatype> + <datatype> <name name="report"/> <desc> <p></p> </desc> </datatype> <datatype> + <name name="report_cb"/> + <desc> + <p>A fun which converts a <seealso marker="#type-report"><c>report()</c> + </seealso> to a format string and arguments, or directly to a string. + See section <seealso marker="logger_chapter#log_message">Log + Message</seealso> in the User's Guide for more + information.</p> + </desc> + </datatype> + <datatype> + <name name="report_cb_config"/> + <desc> + <p></p> + </desc> + </datatype> + <datatype> <name name="timestamp"/> <desc> <p>A timestamp produced @@ -285,13 +309,16 @@ logger:error("error happened because: ~p", [Reason]). % Without macro <item><c>?LOG_INFO(FunOrFormat,Args[,Metadata])</c></item> <item><c>?LOG_DEBUG(StringOrReport[,Metadata])</c></item> <item><c>?LOG_DEBUG(FunOrFormat,Args[,Metadata])</c></item> + <item><c>?LOG(Level,StringOrReport[,Metadata])</c></item> + <item><c>?LOG(Level,FunOrFormat,Args[,Metadata])</c></item> </list> <p>All macros expand to a call to Logger, where <c>Level</c> is - taken from the macro name, and location data is added to the - metadata. See the description of + taken from the macro name, or from the first argument in the + case of the <c>?LOG</c> macro. Location data is added to the + metadata as described under the <seealso marker="#type-metadata"><c>metadata()</c></seealso> - type for more information about the location data.</p> + type definition.</p> <p>The call is wrapped in a case statement and will be evaluated only if <c>Level</c> is equal to or below the configured log @@ -690,15 +717,30 @@ start(_, []) -> </func> <func> - <name name="set_handler_config" arity="3"/> + <name name="set_handler_config" arity="3" clause_i="1"/> + <name name="set_handler_config" arity="3" clause_i="2"/> + <name name="set_handler_config" arity="3" clause_i="3"/> + <name name="set_handler_config" arity="3" clause_i="4"/> + <name name="set_handler_config" arity="3" clause_i="5"/> <fsummary>Add or update configuration data for the specified handler.</fsummary> + <type variable="HandlerId"/> + <type variable="Level" name_i="1"/> + <type variable="FilterDefault" name_i="2"/> + <type variable="Filters" name_i="3"/> + <type variable="Formatter" name_i="4"/> + <type variable="Config" name_i="5"/> + <type variable="Return"/> <desc> <p>Add or update configuration data for the specified handler. If the given <c><anno>Key</anno></c> already exists, its associated value will be changed - to <c><anno>Value</anno></c>. If it does not exist, it will + to the given value. If it does not exist, it will be added.</p> + <p>See the definition of + the <seealso marker="#type-handler_config"> + <c>handler_config()</c></seealso> type for more + information about the different parameters.</p> </desc> </func> @@ -721,13 +763,18 @@ start(_, []) -> </func> <func> - <name name="set_primary_config" arity="2"/> + <name name="set_primary_config" arity="2" clause_i="1"/> + <name name="set_primary_config" arity="2" clause_i="2"/> + <name name="set_primary_config" arity="2" clause_i="3"/> <fsummary>Add or update primary configuration data for Logger.</fsummary> + <type variable="Level" name_i="1"/> + <type variable="FilterDefault" name_i="2"/> + <type variable="Filters" name_i="3"/> <desc> <p>Add or update primary configuration data for Logger. If the given <c><anno>Key</anno></c> already exists, its associated - value will be changed to <c><anno>Value</anno></c>. If it - does not exist, it will be added.</p> + value will be changed to the given value. If it does not + exist, it will be added.</p> </desc> </func> diff --git a/lib/kernel/doc/src/logger_arch.dia b/lib/kernel/doc/src/logger_arch.dia Binary files differnew file mode 100644 index 0000000000..97be31856e --- /dev/null +++ b/lib/kernel/doc/src/logger_arch.dia diff --git a/lib/kernel/doc/src/logger_arch.png b/lib/kernel/doc/src/logger_arch.png Binary files differindex a3a863c511..70933a5a41 100644 --- a/lib/kernel/doc/src/logger_arch.png +++ b/lib/kernel/doc/src/logger_arch.png diff --git a/lib/kernel/doc/src/logger_chapter.xml b/lib/kernel/doc/src/logger_chapter.xml index f4a752bde9..30172f6ca6 100644 --- a/lib/kernel/doc/src/logger_chapter.xml +++ b/lib/kernel/doc/src/logger_chapter.xml @@ -69,6 +69,8 @@ figure shows two log handlers, but any number of handlers can be installed.</p> + <!-- The image is edited with dia in logger_arch.dia file, + and .png file generated with make target 'png'. --> <image file="logger_arch.png"> <icaption>Conceptual Overview</icaption> </image> @@ -192,10 +194,26 @@ the log event's <seealso marker="#metadata">metadata</seealso>. The report callback is a convenience function that the <seealso marker="#formatters">formatter</seealso> can use - to convert the report to a format string and arguments. The + to convert the report to a format string and arguments, or + directly to a string. The formatter can also use its own conversion function, if no callback is provided, or if a customized formatting is desired.</p> + <p>The report callback must be a fun with one or two + arguments. If it takes one argument, this is the report + itself, and the fun returns a format string and arguments:</p> + <pre>fun((<seealso marker="logger#type-report"><c>logger:report()</c></seealso>) -> {<seealso marker="stdlib:io#type-format"><c>io:format()</c></seealso>,[term()]})</pre> + <p>If it takes two arguments, the first is the report, and the + second is a map containing extra data that allows direct + coversion to a string:</p> + <pre>fun((<seealso marker="logger#type-report"><c>logger:report()</c></seealso>,<seealso marker="logger#type-report_cb_config"><c>logger:report_cb_config()</c></seealso>) -> <seealso marker="stdlib:unicode#type-chardata"><c>unicode:chardata()</c></seealso>) + </pre> + <p>The fun must obey the <c>encoding</c>, <c>depth</c> + and <c>chars_limit</c> parameters provided in the second + argument, as the formatter can not do anything useful of these + parameters with the returned string. This variant is used when + the formatting of the report depends on the size and encoding + parameters.</p> <p>Example, format string and arguments:</p> <code>logger:error("The file does not exist: ~ts",[Filename])</code> <p>Example, string:</p> @@ -222,7 +240,7 @@ logger:debug(#{got => connection_request, id => Id, state => State}, with <seealso marker="logger#set_process_metadata-1"> <c>logger:set_process_metadata/1</c></seealso> and <seealso marker="logger#update_process_metadata-1"> - <c>logger:update_process metadata/1</c></seealso>, + <c>logger:update_process_metadata/1</c></seealso>, respectively. This metadata applies to the process on which these calls are made, and Logger adds the metadata to all log events issued on that process.</p> diff --git a/lib/kernel/doc/src/logger_formatter.xml b/lib/kernel/doc/src/logger_formatter.xml index e777afaf86..9226d19834 100644 --- a/lib/kernel/doc/src/logger_formatter.xml +++ b/lib/kernel/doc/src/logger_formatter.xml @@ -78,10 +78,17 @@ format controls ~p and ~w are replaced with ~P and ~W, respectively, and the value is used as the depth parameter. For details, see - <seealso marker="stdlib:io#format-2">io:format/2,3</seealso> + <seealso marker="stdlib:io#format-2"><c>io:format/2,3</c></seealso> in STDLIB.</p> <p>Defaults to <c>unlimited</c>.</p> </item> + <tag><c>encoding = </c><seealso marker="stdlib:unicode#type-encoding"> + <c>unicode:encoding()</c></seealso></tag> + <item> + <p>This parameter must reflect the encoding of the device + that the handler prints to.</p> + <p>Defaults to <c>utf8</c></p> + </item> <tag><c>legacy_header = boolean()</c></tag> <item> <p>If set to <c>true</c> a header field is added to @@ -105,7 +112,8 @@ by <c>chars_limit</c> or <c>depth</c>, it is truncated.</p> <p>Defaults to <c>unlimited</c>.</p> </item> - <tag><c>report_cb = fun((</c><seealso marker="logger#type-report"><c>logger:report()</c></seealso><c>) -> {</c><seealso marker="stdlib:io#type-format"><c>io:format()</c></seealso><c>, [term()]})</c></tag> + <tag><c>report_cb = </c><seealso marker="logger#type-report_cb"> + <c>logger:report_cb()</c></seealso></tag> <item> <p>A report callback is used by the formatter to transform log messages on report form to a format string and @@ -119,9 +127,6 @@ both the default report callback, and any report callback found in metadata. That is, all reports are converted by this configured function.</p> - <p>The value must be a function with arity 1, - returning <c>{Format,Args}</c>, and it will be called - with a report as only argument.</p> </item> <tag><c>single_line = boolean()</c></tag> <item> diff --git a/lib/kernel/doc/src/notes.xml b/lib/kernel/doc/src/notes.xml index 6e88e98c6d..5884f93878 100644 --- a/lib/kernel/doc/src/notes.xml +++ b/lib/kernel/doc/src/notes.xml @@ -314,6 +314,22 @@ </section> +<section><title>Kernel 5.4.3.2</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Non semantic change in dist_util.erl to silence dialyzer + warning.</p> + <p> + Own Id: OTP-15170</p> + </item> + </list> + </section> + +</section> + <section><title>Kernel 5.4.3.1</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/kernel/include/logger.hrl b/lib/kernel/include/logger.hrl index 2143ccd297..b09977e0f2 100644 --- a/lib/kernel/include/logger.hrl +++ b/lib/kernel/include/logger.hrl @@ -32,6 +32,10 @@ -define(LOG_DEBUG(A,B),?DO_LOG(debug,[A,B])). -define(LOG_DEBUG(A,B,C),?DO_LOG(debug,[A,B,C])). +-define(LOG(L,A),?DO_LOG(L,[A])). +-define(LOG(L,A,B),?DO_LOG(L,[A,B])). +-define(LOG(L,A,B,C),?DO_LOG(L,[A,B,C])). + -define(LOCATION,#{mfa=>{?MODULE,?FUNCTION_NAME,?FUNCTION_ARITY}, line=>?LINE, file=>?FILE}). diff --git a/lib/kernel/src/Makefile b/lib/kernel/src/Makefile index c595c25341..57f17defc8 100644 --- a/lib/kernel/src/Makefile +++ b/lib/kernel/src/Makefile @@ -112,7 +112,8 @@ MODULES = \ logger \ logger_backend \ logger_config \ - logger_std_h \ + logger_handler_watcher \ + logger_std_h \ logger_disk_log_h \ logger_h_common \ logger_filters \ diff --git a/lib/kernel/src/error_logger.erl b/lib/kernel/src/error_logger.erl index a7e7f19167..ad8c937882 100644 --- a/lib/kernel/src/error_logger.erl +++ b/lib/kernel/src/error_logger.erl @@ -74,8 +74,8 @@ start() -> type => worker, modules => dynamic}, case supervisor:start_child(logger_sup, ErrorLogger) of - {ok,_} -> - ok; + {ok,Pid} -> + ok = logger_handler_watcher:register_handler(?MODULE,Pid); Error -> Error end; @@ -95,9 +95,14 @@ start_link() -> %%% Stop the event manager -spec stop() -> ok. stop() -> - _ = supervisor:terminate_child(logger_sup,?MODULE), - _ = supervisor:delete_child(logger_sup,?MODULE), - ok. + case whereis(?MODULE) of + undefined -> + ok; + _Pid -> + _ = gen_event:stop(?MODULE,{shutdown,stopped},infinity), + _ = supervisor:delete_child(logger_sup,?MODULE), + ok + end. %%%----------------------------------------------------------------- %%% Callbacks for logger diff --git a/lib/kernel/src/kernel.app.src b/lib/kernel/src/kernel.app.src index 47dd7c03d5..4933eae76f 100644 --- a/lib/kernel/src/kernel.app.src +++ b/lib/kernel/src/kernel.app.src @@ -67,6 +67,7 @@ logger_filters, logger_formatter, logger_h_common, + logger_handler_watcher, logger_server, logger_simple_h, logger_std_h, @@ -129,6 +130,7 @@ kernel_refc, kernel_sup, logger, + logger_handler_watcher, logger_sup, net_kernel, net_sup, diff --git a/lib/kernel/src/logger.erl b/lib/kernel/src/logger.erl index 0a9b1672ec..ffc90f4fc5 100644 --- a/lib/kernel/src/logger.erl +++ b/lib/kernel/src/logger.erl @@ -74,6 +74,11 @@ -type level() :: emergency | alert | critical | error | warning | notice | info | debug. -type report() :: map() | [{atom(),term()}]. +-type report_cb() :: fun((report()) -> {io:format(),[term()]}) | + fun((report(),report_cb_config()) -> unicode:chardata()). +-type report_cb_config() :: #{encoding := unicode:encoding(), + depth := pos_integer() | unlimited, + chars_limit := pos_integer() | unlimited}. -type msg_fun() :: fun((term()) -> {io:format(),[term()]} | report() | unicode:chardata()). @@ -84,7 +89,7 @@ file => file:filename(), line => non_neg_integer(), domain => [atom()], - report_cb => fun((report()) -> {io:format(),[term()]}), + report_cb => report_cb(), atom() => term()}. -type location() :: #{mfa := {module(),atom(),non_neg_integer()}, file := file:filename(), @@ -110,10 +115,22 @@ -type config_handler() :: {handler, handler_id(), module(), handler_config()}. --export_type([log_event/0,level/0,report/0,msg_fun/0,metadata/0, - primary_config/0,handler_config/0,handler_id/0, - filter_id/0,filter/0,filter_arg/0,filter_return/0, - config_handler/0,formatter_config/0]). +-export_type([log_event/0, + level/0, + report/0, + report_cb/0, + report_cb_config/0, + msg_fun/0, + metadata/0, + primary_config/0, + handler_config/0, + handler_id/0, + filter_id/0, + filter/0, + filter_arg/0, + filter_return/0, + config_handler/0, + formatter_config/0]). %%%----------------------------------------------------------------- %%% API @@ -352,9 +369,12 @@ add_handler(HandlerId,Module,Config) -> remove_handler(HandlerId) -> logger_server:remove_handler(HandlerId). --spec set_primary_config(Key,Value) -> ok | {error,term()} when - Key :: atom(), - Value :: term(). +-spec set_primary_config(level,Level) -> ok | {error,term()} when + Level :: level() | all | none; + (filter_default,FilterDefault) -> ok | {error,term()} when + FilterDefault :: log | stop; + (filters,Filters) -> ok | {error,term()} when + Filters :: [{filter_id(),filter()}]. set_primary_config(Key,Value) -> logger_server:set_config(primary,Key,Value). @@ -363,10 +383,26 @@ set_primary_config(Key,Value) -> set_primary_config(Config) -> logger_server:set_config(primary,Config). --spec set_handler_config(HandlerId,Key,Value) -> ok | {error,term()} when +-spec set_handler_config(HandlerId,level,Level) -> Return when HandlerId :: handler_id(), - Key :: atom(), - Value :: term(). + Level :: level() | all | none, + Return :: ok | {error,term()}; + (HandlerId,filter_default,FilterDefault) -> Return when + HandlerId :: handler_id(), + FilterDefault :: log | stop, + Return :: ok | {error,term()}; + (HandlerId,filters,Filters) -> Return when + HandlerId :: handler_id(), + Filters :: [{filter_id(),filter()}], + Return :: ok | {error,term()}; + (HandlerId,formatter,Formatter) -> Return when + HandlerId :: handler_id(), + Formatter :: {module(), formatter_config()}, + Return :: ok | {error,term()}; + (HandlerId,config,Config) -> Return when + HandlerId :: handler_id(), + Config :: term(), + Return :: ok | {error,term()}. set_handler_config(HandlerId,Key,Value) -> logger_server:set_config(HandlerId,Key,Value). @@ -651,7 +687,7 @@ get_logger_type() -> get_logger_level() -> case application:get_env(kernel,logger_level,info) of - Level when ?IS_LEVEL(Level) -> + Level when ?IS_LEVEL(Level); Level=:=all; Level=:=none -> Level; Level -> throw({logger_level, Level}) diff --git a/lib/kernel/src/logger_disk_log_h.erl b/lib/kernel/src/logger_disk_log_h.erl index 0a72654e11..e56531c3cb 100644 --- a/lib/kernel/src/logger_disk_log_h.erl +++ b/lib/kernel/src/logger_disk_log_h.erl @@ -488,7 +488,8 @@ start(Name, Config, HandlerState) -> type => worker, modules => [?MODULE]}, case supervisor:start_child(logger_sup, LoggerDLH) of - {ok,_Pid,Config1} -> + {ok,Pid,Config1} -> + ok = logger_handler_watcher:register_handler(Name,Pid), {ok,Config1}; Error -> Error @@ -506,8 +507,11 @@ stop(Name) -> %% system termination in order to avoid circular attempts %% at removing the handler (implying deadlocks and %% timeouts). + %% And we don't need to do supervisor:delete_child, since + %% the restart type is temporary, which means that the + %% child specification is automatically removed from the + %% supervisor when the process dies. _ = gen_server:call(Pid, stop), - _ = supervisor:delete_child(logger_sup, Name), ok end. diff --git a/lib/kernel/src/logger_formatter.erl b/lib/kernel/src/logger_formatter.erl index 456b0c9e8d..a5c6984bc6 100644 --- a/lib/kernel/src/logger_formatter.erl +++ b/lib/kernel/src/logger_formatter.erl @@ -26,16 +26,17 @@ %%%----------------------------------------------------------------- %%% Types --type config() :: #{chars_limit=>pos_integer()| unlimited, - depth=>pos_integer() | unlimited, - legacy_header=>boolean(), - max_size=>pos_integer() | unlimited, - report_cb=>fun((logger:report()) -> {io:format(),[term()]}), - single_line=>boolean(), - template=>template(), - time_designator=>byte(), - time_offset=>integer()|[byte()]}. --type template() :: [metakey()|{metakey(),template(),template()}|string()]. +-type config() :: #{chars_limit => pos_integer() | unlimited, + depth => pos_integer() | unlimited, + encoding => unicode:encoding(), + legacy_header => boolean(), + max_size => pos_integer() | unlimited, + report_cb => logger:report_cb(), + single_line => boolean(), + template => template(), + time_designator => byte(), + time_offset => integer() | [byte()]}. +-type template() :: [metakey() | {metakey(),template(),template()} | string()]. -type metakey() :: atom() | [atom()]. %%%----------------------------------------------------------------- @@ -76,7 +77,7 @@ format(#{level:=Level,msg:=Msg0,meta:=Meta},Config0) %% Trim leading and trailing whitespaces, and replace %% newlines with ", " re:replace(string:trim(MsgStr0),",?\r?\n\s*",", ", - [{return,list},global]); + [{return,list},global,unicode]); _false -> MsgStr0 end; @@ -119,65 +120,96 @@ value(_,_) -> to_string(time,Time,Config) -> format_time(Time,Config); -to_string(mfa,MFA,_Config) -> - format_mfa(MFA); -to_string(_,Value,_Config) -> - to_string(Value). +to_string(mfa,MFA,Config) -> + format_mfa(MFA,Config); +to_string(_,Value,Config) -> + to_string(Value,Config). -to_string(X) when is_atom(X) -> +to_string(X,_) when is_atom(X) -> atom_to_list(X); -to_string(X) when is_integer(X) -> +to_string(X,_) when is_integer(X) -> integer_to_list(X); -to_string(X) when is_pid(X) -> +to_string(X,_) when is_pid(X) -> pid_to_list(X); -to_string(X) when is_reference(X) -> +to_string(X,_) when is_reference(X) -> ref_to_list(X); -to_string(X) when is_list(X) -> - case io_lib:printable_unicode_list(lists:flatten(X)) of +to_string(X,Config) when is_list(X) -> + case printable_list(lists:flatten(X)) of true -> X; - _ -> io_lib:format("~tp",[X]) + _ -> io_lib:format(p(Config),[X]) end; -to_string(X) -> - io_lib:format("~tp",[X]). +to_string(X,Config) -> + io_lib:format(p(Config),[X]). + +printable_list([]) -> + false; +printable_list(X) -> + io_lib:printable_list(X). format_msg({string,Chardata},Meta,Config) -> - format_msg({"~ts",[Chardata]},Meta,Config); -format_msg({report,_}=Msg,Meta,#{report_cb:=Fun}=Config) when is_function(Fun,1) -> + format_msg({s(Config),[Chardata]},Meta,Config); +format_msg({report,_}=Msg,Meta,#{report_cb:=Fun}=Config) + when is_function(Fun,1); is_function(Fun,2) -> format_msg(Msg,Meta#{report_cb=>Fun},maps:remove(report_cb,Config)); format_msg({report,Report},#{report_cb:=Fun}=Meta,Config) when is_function(Fun,1) -> try Fun(Report) of {Format,Args} when is_list(Format), is_list(Args) -> format_msg({Format,Args},maps:remove(report_cb,Meta),Config); Other -> - format_msg({"REPORT_CB ERROR: ~tp; Returned: ~tp", + P = p(Config), + format_msg({"REPORT_CB/1 ERROR: "++P++"; Returned: "++P, + [Report,Other]},Meta,Config) + catch C:R:S -> + P = p(Config), + format_msg({"REPORT_CB/1 CRASH: "++P++"; Reason: "++P, + [Report,{C,R,logger:filter_stacktrace(?MODULE,S)}]}, + Meta,Config) + end; +format_msg({report,Report},#{report_cb:=Fun}=Meta,Config) when is_function(Fun,2) -> + try Fun(Report,maps:with([encoding,depth,chars_limit],Config)) of + String when ?IS_STRING(String) -> + try unicode:characters_to_list(String) + catch _:_ -> + P = p(Config), + format_msg({"REPORT_CB/2 ERROR: "++P++"; Returned: "++P, + [Report,String]},Meta,Config) + end; + Other -> + P = p(Config), + format_msg({"REPORT_CB/2 ERROR: "++P++"; Returned: "++P, [Report,Other]},Meta,Config) - catch C:R -> - format_msg({"REPORT_CB CRASH: ~tp; Reason: ~tp", - [Report,{C,R}]},Meta,Config) + catch C:R:S -> + P = p(Config), + format_msg({"REPORT_CB/2 CRASH: "++P++"; Reason: "++P, + [Report,{C,R,logger:filter_stacktrace(?MODULE,S)}]}, + Meta,Config) end; format_msg({report,Report},Meta,Config) -> format_msg({report,Report}, Meta#{report_cb=>fun logger:format_report/1}, Config); -format_msg(Msg,_Meta,#{depth:=Depth,chars_limit:=CharsLimit}) -> - limit_size(Msg, Depth, CharsLimit). - -limit_size(Msg,Depth,unlimited) -> - limit_size(Msg,Depth,[]); -limit_size(Msg,Depth,CharsLimit) when is_integer(CharsLimit) -> - limit_size(Msg,Depth,[{chars_limit,CharsLimit}]); -limit_size({Format,Args},unlimited,Opts) when is_list(Opts) -> +format_msg(Msg,_Meta,#{depth:=Depth,chars_limit:=CharsLimit,encoding:=Enc}) -> + limit_size(Msg, Depth, CharsLimit, Enc). + +limit_size(Msg,Depth,unlimited,Enc) -> + limit_size(Msg,Depth,[],Enc); +limit_size(Msg,Depth,CharsLimit,Enc) when is_integer(CharsLimit) -> + limit_size(Msg,Depth,[{chars_limit,CharsLimit}],Enc); +limit_size({Format,Args},unlimited,Opts,Enc) when is_list(Opts) -> try io_lib:format(Format,Args,Opts) catch _:_ -> - io_lib:format("FORMAT ERROR: ~tp - ~tp",[Format,Args],Opts) + P = p(Enc), + io_lib:format("FORMAT ERROR: "++P++" - "++P,[Format,Args],Opts) end; -limit_size({Format0,Args},Depth,Opts) when is_integer(Depth) -> +limit_size({Format0,Args},Depth,Opts,Enc) when is_integer(Depth) -> try Format1 = io_lib:scan_format(Format0, Args), Format = limit_format(Format1, Depth), io_lib:build_text(Format,Opts) catch _:_ -> - limit_size({"FORMAT ERROR: ~tp - ~tp",[Format0,Args]},Depth,Opts) + P = p(Enc), + limit_size({"FORMAT ERROR: "++P++" - "++P,[Format0,Args]}, + Depth,Opts,Enc) end. limit_format([#{control_char:=C0}=M0|T], Depth) when C0 =:= $p; @@ -225,22 +257,23 @@ timestamp_to_datetimemicro(SysTime,Config) when is_integer(SysTime) -> end, {Date,Time,Micro,UtcStr}. -format_mfa({M,F,A}) when is_atom(M), is_atom(F), is_integer(A) -> +format_mfa({M,F,A},_) when is_atom(M), is_atom(F), is_integer(A) -> atom_to_list(M)++":"++atom_to_list(F)++"/"++integer_to_list(A); -format_mfa({M,F,A}) when is_atom(M), is_atom(F), is_list(A) -> - format_mfa({M,F,length(A)}); -format_mfa(MFA) -> - to_string(MFA). +format_mfa({M,F,A},Config) when is_atom(M), is_atom(F), is_list(A) -> + format_mfa({M,F,length(A)},Config); +format_mfa(MFA,Config) -> + to_string(MFA,Config). maybe_add_legacy_header(Level, #{time:=Timestamp}=Meta, #{legacy_header:=true}=Config) -> #{title:=Title}=MyMeta = add_legacy_title(Level,Meta,Config), - {{Y,Mo,D},{H,Mi,S},Micro,UtcStr} = + {{Y,Mo,D},{H,Mi,Sec},Micro,UtcStr} = timestamp_to_datetimemicro(Timestamp,Config), + S = s(Config), Header = - io_lib:format("=~ts==== ~w-~s-~4w::~2..0w:~2..0w:~2..0w.~6..0w ~s===", - [Title,D,month(Mo),Y,H,Mi,S,Micro,UtcStr]), + io_lib:format("="++S++"==== ~w-~s-~4w::~2..0w:~2..0w:~2..0w.~6..0w ~s===", + [Title,D,month(Mo),Y,H,Mi,Sec,Micro,UtcStr]), Meta#{?MODULE=>MyMeta#{header=>Header}}; maybe_add_legacy_header(_,Meta,_) -> Meta. @@ -280,10 +313,11 @@ month(12) -> "Dec". %% configuration map add_default_config(Config0) -> Default = - #{legacy_header=>false, + #{chars_limit=>unlimited, + encoding=>utf8, error_logger_notice_header=>info, + legacy_header=>false, single_line=>true, - chars_limit=>unlimited, time_designator=>$T}, MaxSize = get_max_size(maps:get(max_size,Config0,undefined)), Depth = get_depth(maps:get(depth,Config0,undefined)), @@ -369,7 +403,8 @@ do_check_config([{legacy_header,LH}|Config]) when is_boolean(LH) -> do_check_config([{error_logger_notice_header,ELNH}|Config]) when ELNH == info; ELNH == notice -> do_check_config(Config); -do_check_config([{report_cb,RCB}|Config]) when is_function(RCB,1) -> +do_check_config([{report_cb,RCB}|Config]) when is_function(RCB,1); + is_function(RCB,2) -> do_check_config(Config); do_check_config([{template,T}|Config]) -> case check_template(T) of @@ -456,3 +491,17 @@ check_timezone(Tz) -> catch _:_ -> error end. + +p(#{encoding:=Enc}) -> + p(Enc); +p(latin1) -> + "~p"; +p(_) -> + "~tp". + +s(#{encoding:=Enc}) -> + s(Enc); +s(latin1) -> + "~s"; +s(_) -> + "~ts". diff --git a/lib/kernel/src/logger_h_common.erl b/lib/kernel/src/logger_h_common.erl index a40345dddc..854e5479b9 100644 --- a/lib/kernel/src/logger_h_common.erl +++ b/lib/kernel/src/logger_h_common.erl @@ -309,19 +309,6 @@ stop_or_restart(Name, {shutdown,Reason={overloaded,_Name,_QLen,_Mem}}, end, spawn(RemoveAndRestart), ok; - -stop_or_restart(Name, shutdown, _State) -> - %% Probably terminated by supervisor. Remove the handler to avoid - %% error printouts due to failing handler. - _ = case logger:get_handler_config(Name) of - {ok,_} -> - %% Spawning to avoid deadlock - spawn(logger,remove_handler,[Name]); - _ -> - ok - end, - ok; - stop_or_restart(_Name, _Reason, _State) -> ok. diff --git a/lib/kernel/src/logger_handler_watcher.erl b/lib/kernel/src/logger_handler_watcher.erl new file mode 100644 index 0000000000..b75c74c643 --- /dev/null +++ b/lib/kernel/src/logger_handler_watcher.erl @@ -0,0 +1,113 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2018. All Rights Reserved. +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%% +%% %CopyrightEnd% +%% +-module(logger_handler_watcher). + +-behaviour(gen_server). + +%% API +-export([start_link/0]). +-export([register_handler/2]). + +%% gen_server callbacks +-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2]). + +-define(SERVER, ?MODULE). + +-record(state, {handlers}). + +%%%=================================================================== +%%% API +%%%=================================================================== + +-spec start_link() -> {ok, Pid :: pid()} | + {error, Error :: {already_started, pid()}} | + {error, Error :: term()} | + ignore. +start_link() -> + gen_server:start_link({local, ?SERVER}, ?MODULE, [], []). + +-spec register_handler(Id::logger:handler_id(),Pid::pid()) -> ok. +register_handler(Id,Pid) -> + gen_server:call(?SERVER,{register,Id,Pid}). + +%%%=================================================================== +%%% gen_server callbacks +%%%=================================================================== + +-spec init(Args :: term()) -> {ok, State :: term()} | + {ok, State :: term(), Timeout :: timeout()} | + {ok, State :: term(), hibernate} | + {stop, Reason :: term()} | + ignore. +init([]) -> + process_flag(trap_exit, true), + {ok, #state{handlers=[]}}. + +-spec handle_call(Request :: term(), From :: {pid(), term()}, State :: term()) -> + {reply, Reply :: term(), NewState :: term()} | + {reply, Reply :: term(), NewState :: term(), Timeout :: timeout()} | + {reply, Reply :: term(), NewState :: term(), hibernate} | + {noreply, NewState :: term()} | + {noreply, NewState :: term(), Timeout :: timeout()} | + {noreply, NewState :: term(), hibernate} | + {stop, Reason :: term(), Reply :: term(), NewState :: term()} | + {stop, Reason :: term(), NewState :: term()}. +handle_call({register,Id,Pid}, _From, #state{handlers=Hs}=State) -> + Ref = erlang:monitor(process,Pid), + Hs1 = lists:keystore(Id,1,Hs,{Id,Ref}), + {reply, ok, State#state{handlers=Hs1}}. + +-spec handle_cast(Request :: term(), State :: term()) -> + {noreply, NewState :: term()} | + {noreply, NewState :: term(), Timeout :: timeout()} | + {noreply, NewState :: term(), hibernate} | + {stop, Reason :: term(), NewState :: term()}. +handle_cast(_Request, State) -> + {noreply, State}. + +-spec handle_info(Info :: timeout() | term(), State :: term()) -> + {noreply, NewState :: term()} | + {noreply, NewState :: term(), Timeout :: timeout()} | + {noreply, NewState :: term(), hibernate} | + {stop, Reason :: normal | term(), NewState :: term()}. +handle_info({'DOWN',Ref,process,_,shutdown}, #state{handlers=Hs}=State) -> + case lists:keytake(Ref,2,Hs) of + {value,{Id,Ref},Hs1} -> + %% Probably terminated by supervisor. Remove the handler to avoid + %% error printouts due to failing handler. + _ = case logger:get_handler_config(Id) of + {ok,_} -> + logger:remove_handler(Id); + _ -> + ok + end, + {noreply,State#state{handlers=Hs1}}; + false -> + {noreply, State} + end; +handle_info({'DOWN',Ref,process,_,_OtherReason}, #state{handlers=Hs}=State) -> + {noreply,State#state{handlers=lists:keydelete(Ref,2,Hs)}}; +handle_info(_Other,State) -> + {noreply,State}. + +-spec terminate(Reason :: normal | shutdown | {shutdown, term()} | term(), + State :: term()) -> any(). +terminate(_Reason, _State) -> + ok. diff --git a/lib/kernel/src/logger_std_h.erl b/lib/kernel/src/logger_std_h.erl index 480fafd6d8..9a2a1443b3 100644 --- a/lib/kernel/src/logger_std_h.erl +++ b/lib/kernel/src/logger_std_h.erl @@ -467,7 +467,8 @@ start(Name, Config, HandlerState) -> type => worker, modules => [?MODULE]}, case supervisor:start_child(logger_sup, LoggerStdH) of - {ok,_Pid,Config1} -> + {ok,Pid,Config1} -> + ok = logger_handler_watcher:register_handler(Name,Pid), {ok,Config1}; Error -> Error @@ -485,8 +486,11 @@ stop(Name) -> %% system termination in order to avoid circular attempts %% at removing the handler (implying deadlocks and %% timeouts). + %% And we don't need to do supervisor:delete_child, since + %% the restart type is temporary, which means that the + %% child specification is automatically removed from the + %% supervisor when the process dies. _ = gen_server:call(Pid, stop), - _ = supervisor:delete_child(logger_sup, Name), ok end. diff --git a/lib/kernel/src/logger_sup.erl b/lib/kernel/src/logger_sup.erl index dcdcdad0bd..3d6f482e20 100644 --- a/lib/kernel/src/logger_sup.erl +++ b/lib/kernel/src/logger_sup.erl @@ -46,7 +46,11 @@ init([]) -> intensity => 1, period => 5}, - {ok, {SupFlags, []}}. + Watcher = #{id => logger_handler_watcher, + start => {logger_handler_watcher, start_link, []}, + shutdown => brutal_kill}, + + {ok, {SupFlags, [Watcher]}}. %%%=================================================================== %%% Internal functions diff --git a/lib/kernel/test/file_SUITE.erl b/lib/kernel/test/file_SUITE.erl index 23913ac56a..e784c06865 100644 --- a/lib/kernel/test/file_SUITE.erl +++ b/lib/kernel/test/file_SUITE.erl @@ -1367,6 +1367,10 @@ file_info_basic_file(Config) when is_list(Config) -> io:put_chars(Fd1, "foo bar"), ok = ?FILE_MODULE:close(Fd1), + %% Don't crash the file server when passing incorrect arguments. + {error,badarg} = ?FILE_MODULE:read_file_info(Name, [{time, gurka}]), + {error,badarg} = ?FILE_MODULE:read_file_info([#{} | gaffel]), + %% Test that the file has the expected attributes. %% The times are tricky, so we will save them to a separate test case. {ok,FileInfo} = ?FILE_MODULE:read_file_info(Name), diff --git a/lib/kernel/test/logger_SUITE.erl b/lib/kernel/test/logger_SUITE.erl index b367b4dd54..8f74ebdc47 100644 --- a/lib/kernel/test/logger_SUITE.erl +++ b/lib/kernel/test/logger_SUITE.erl @@ -355,6 +355,7 @@ log_all_levels_api(cleanup,_Config) -> macros(_Config) -> ok = logger:add_handler(h1,?MODULE,#{level=>all,filter_default=>log}), test_macros(emergency), + test_log_macro(alert), ok. macros(cleanup,_Config) -> @@ -469,7 +470,11 @@ filter_failed(_Config) -> %% Logger filters {error,{invalid_filter,_}} = logger:add_primary_filter(lf,{fun(_) -> ok end,args}), - ok = logger:add_primary_filter(lf,{fun(_,_) -> a=b end,args}), + ok = logger:add_primary_filter(lf, + {fun(_,_) -> + erlang:error({badmatch,b}) + end, + args}), #{filters:=[_]} = logger:get_primary_config(), ok = logger:notice(M1=?map_rep), ok = check_logged(notice,M1,#{}), @@ -487,7 +492,11 @@ filter_failed(_Config) -> {error,{not_found,h0}} = logger:remove_handler_filter(h0,hf), {error,{invalid_filter,_}} = logger:add_handler_filter(h1,hf,{fun(_) -> ok end,args}), - ok = logger:add_handler_filter(h1,hf,{fun(_,_) -> a=b end,args}), + ok = logger:add_handler_filter(h1,hf, + {fun(_,_) -> + erlang:error({badmatch,b}) + end, + args}), {ok,#{filters:=[_]}} = logger:get_handler_config(h1), ok = logger:notice(M3=?map_rep), ok = check_logged(notice,M3,#{}), @@ -523,7 +532,11 @@ handler_failed(_Config) -> false = lists:search(fun(#{id:=h1}) -> true; (_) -> false end,H1), {error,{not_found,h1}} = logger:remove_handler(h1), - ok = logger:add_handler(h2,?MODULE,#{filter_default=>log,log_call=>fun() -> a = b end}), + ok = logger:add_handler(h2,?MODULE, + #{filter_default => log, + log_call => fun() -> + erlang:error({badmatch,b}) + end}), {error,{already_exist,h2}} = logger:add_handler(h2,othermodule,#{}), [add] = test_server:messages_get(), @@ -534,7 +547,7 @@ handler_failed(_Config) -> {error,{not_found,h2}} = logger:remove_handler(h2), CallAddHandler = fun() -> logger:add_handler(h2,?MODULE,#{}) end, - CrashHandler = fun() -> a = b end, + CrashHandler = fun() -> erlang:error({badmatch,b}) end, KillHandler = fun() -> exit(self(), die) end, {error,{handler_not_added,{attempting_syncronous_call_to_self,_}}} = @@ -1009,6 +1022,34 @@ test_macros(emergency=Level) -> [{F2,x},{error,fun_that_crashes}],#{}), ok. +test_log_macro(Level) -> + ?LOG(Level,#{Level=>rep}), + ok = check_logged(Level,#{Level=>rep},?MY_LOC(1)), + ?LOG(Level,#{Level=>rep},#{my=>meta}), + ok = check_logged(Level,#{Level=>rep},(?MY_LOC(1))#{my=>meta}), + ?LOG(Level,"~w: ~w",[Level,fa]), + ok = check_logged(Level,"~w: ~w",[Level,fa],?MY_LOC(1)), + ?LOG(Level,"~w: ~w ~w",[Level,fa,meta],#{my=>meta}), + ok = check_logged(Level,"~w: ~w ~w",[Level,fa,meta],(?MY_LOC(1))#{my=>meta}), + ?LOG(Level,fun(x) -> {"~w: ~w ~w",[Level,fun_to_fa,meta]} end, + x, #{my=>meta}), + ok = check_logged(Level,"~w: ~w ~w",[Level,fun_to_fa,meta], + (?MY_LOC(3))#{my=>meta}), + ?LOG(Level,fun(x) -> #{Level=>fun_to_r,meta=>true} end, x, #{my=>meta}), + ok = check_logged(Level,#{Level=>fun_to_r,meta=>true}, + (?MY_LOC(2))#{my=>meta}), + ?LOG(Level,fun(x) -> <<"fun_to_s">> end,x,#{}), + ok = check_logged(Level,<<"fun_to_s">>,?MY_LOC(1)), + F1=fun(x) -> {fun_to_bad} end, + ?LOG(Level,F1,x,#{}), + ok = check_logged(Level,"LAZY_FUN ERROR: ~tp; Returned: ~tp", + [{F1,x},{fun_to_bad}],#{}), + F2=fun(x) -> erlang:error(fun_that_crashes) end, + ?LOG(Level,F2,x,#{}), + ok = check_logged(Level,"LAZY_FUN CRASH: ~tp; Reason: ~tp", + [{F2,x},{error,fun_that_crashes}],#{}), + ok. + %%%----------------------------------------------------------------- %%% Called by macro ?TRY(X) my_try(Fun) -> diff --git a/lib/kernel/test/logger_disk_log_h_SUITE.erl b/lib/kernel/test/logger_disk_log_h_SUITE.erl index 7e5b574869..a4b15c841b 100644 --- a/lib/kernel/test/logger_disk_log_h_SUITE.erl +++ b/lib/kernel/test/logger_disk_log_h_SUITE.erl @@ -1551,25 +1551,30 @@ h_proc_name() -> h_proc_name(Name) -> list_to_atom(lists:concat([logger_disk_log_h,"_",Name])). -file_delete(Log) -> - file:delete(Log). - wait_for_process_up(T) -> - wait_for_process_up(h_proc_name(),T). + wait_for_process_up(?MODULE, h_proc_name(), T). -wait_for_process_up(Name,T) -> +wait_for_process_up(Name, RegName, T) -> N = (T div 500) + 1, - wait_for_process_up1(Name,N). + wait_for_process_up1(Name, RegName, N). -wait_for_process_up1(Name,0) -> +wait_for_process_up1(_Name, _RegName, 0) -> error; -wait_for_process_up1(Name,N) -> +wait_for_process_up1(Name, RegName, N) -> timer:sleep(500), - case whereis(Name) of + case whereis(RegName) of Pid when is_pid(Pid) -> - %% ct:pal("Process ~p up (~p tries left)",[Name,N]), - {ok,Pid}; + case logger:get_handler_config(Name) of + {ok,_} -> + %% ct:pal("Process ~p up (~p tries left)",[Name,N]), + {ok,Pid}; + _ -> + wait_for_process_up1(Name, RegName, N-1) + end; undefined -> %% ct:pal("Waiting for process ~p (~p tries left)",[Name,N]), - wait_for_process_up1(Name,N-1) + wait_for_process_up1(Name, RegName, N-1) end. + +file_delete(Log) -> + file:delete(Log). diff --git a/lib/kernel/test/logger_env_var_SUITE.erl b/lib/kernel/test/logger_env_var_SUITE.erl index 04a4364947..e8d1a313dc 100644 --- a/lib/kernel/test/logger_env_var_SUITE.erl +++ b/lib/kernel/test/logger_env_var_SUITE.erl @@ -71,6 +71,7 @@ all() -> sasl_compatible_false, sasl_compatible_false_no_progress, sasl_compatible, + all_logger_level, {group,bad}, {group,error_logger}, {group,logger} @@ -572,6 +573,24 @@ sasl_compatible(Config) -> 0),% progress in std logger ok. +all_logger_level(Config) -> + [all_logger_level(Config,Level) || Level <- [none, + emergency, + alert, + critical, + error, + warning, + notice, + info, + debug, + all]], + ok. + +all_logger_level(Config,Level) -> + {ok,#{primary:=#{level:=Level}},Node} = setup(Config,[{logger_level,Level}]), + true = test_server:stop_node(Node), + ok. + bad_error_logger(Config) -> error = setup(Config,[{error_logger,baddest}]). diff --git a/lib/kernel/test/logger_formatter_SUITE.erl b/lib/kernel/test/logger_formatter_SUITE.erl index 8fe8d5199b..aa8dc42691 100644 --- a/lib/kernel/test/logger_formatter_SUITE.erl +++ b/lib/kernel/test/logger_formatter_SUITE.erl @@ -312,30 +312,48 @@ format_msg(_Config) -> #{report_cb=>fun(_)-> faulty_return end}, #{template=>Template}), ct:log(String5), - "REPORT_CB ERROR: term; Returned: faulty_return" = String5, + "REPORT_CB/1 ERROR: term; Returned: faulty_return" = String5, String6 = format(info,{report,term}, #{report_cb=>fun(_)-> erlang:error(fun_crashed) end}, #{template=>Template}), ct:log(String6), - "REPORT_CB CRASH: term; Reason: {error,fun_crashed}" = String6, + "REPORT_CB/1 CRASH: term; Reason: {error,fun_crashed,"++_ = String6, + + String7 = format(info,{report,term}, + #{report_cb=>fun(_,_)-> ['not',a,string] end}, + #{template=>Template}), + ct:log(String7), + "REPORT_CB/2 ERROR: term; Returned: ['not',a,string]" = String7, + + String8 = format(info,{report,term}, + #{report_cb=>fun(_,_)-> faulty_return end}, + #{template=>Template}), + ct:log(String8), + "REPORT_CB/2 ERROR: term; Returned: faulty_return" = String8, + + String9 = format(info,{report,term}, + #{report_cb=>fun(_,_)-> erlang:error(fun_crashed) end}, + #{template=>Template}), + ct:log(String9), + "REPORT_CB/2 CRASH: term; Reason: {error,fun_crashed,"++_ = String9, %% strings are not formatted - String7 = format(info,{string,"string"}, + String10 = format(info,{string,"string"}, #{report_cb=>fun(_)-> {"formatted",[]} end}, #{template=>Template}), - ct:log(String7), - "string" = String7, + ct:log(String10), + "string" = String10, - String8 = format(info,{string,['not',printable,list]}, + String11 = format(info,{string,['not',printable,list]}, #{report_cb=>fun(_)-> {"formatted",[]} end}, #{template=>Template}), - ct:log("~ts",[String8]), % avoiding ct_log crash - "FORMAT ERROR: \"~ts\" - [['not',printable,list]]" = String8, + ct:log("~ts",[String11]), % avoiding ct_log crash + "FORMAT ERROR: \"~ts\" - [['not',printable,list]]" = String11, - String9 = format(info,{string,"string"},#{},#{template=>Template}), - ct:log(String9), - "string" = String9, + String12 = format(info,{string,"string"},#{},#{template=>Template}), + ct:log(String12), + "string" = String12, ok. @@ -639,8 +657,10 @@ check_config(_Config) -> ?cfgerr({max_size,bad}) = logger_formatter:check_config(#{max_size => bad}), + ok = + logger_formatter:check_config(#{report_cb => fun(_,_) -> "" end}), ?cfgerr({report_cb,F}) = - logger_formatter:check_config(#{report_cb => F=fun(_,_) -> {"",[]} end}), + logger_formatter:check_config(#{report_cb => F=fun(_,_,_) -> {"",[]} end}), ?cfgerr({report_cb,bad}) = logger_formatter:check_config(#{report_cb => bad}), diff --git a/lib/kernel/test/logger_std_h_SUITE.erl b/lib/kernel/test/logger_std_h_SUITE.erl index ca54458ac1..0930cd4211 100644 --- a/lib/kernel/test/logger_std_h_SUITE.erl +++ b/lib/kernel/test/logger_std_h_SUITE.erl @@ -1570,27 +1570,29 @@ h_proc_name() -> h_proc_name(Name) -> ?name_to_reg_name(logger_std_h,Name). -file_delete(Log) -> - file:delete(Log). - wait_for_process_up(T) -> - wait_for_process_up(h_proc_name(),T). + wait_for_process_up(?MODULE, h_proc_name(), T). -wait_for_process_up(Name,T) -> +wait_for_process_up(Name, RegName, T) -> N = (T div 500) + 1, - wait_for_process_up1(Name,N). + wait_for_process_up1(Name, RegName, N). -wait_for_process_up1(_Name,0) -> +wait_for_process_up1(_Name, _RegName, 0) -> error; -wait_for_process_up1(Name,N) -> +wait_for_process_up1(Name, RegName, N) -> timer:sleep(500), - case whereis(Name) of + case whereis(RegName) of Pid when is_pid(Pid) -> - %% ct:pal("Process ~p up (~p tries left)",[Name,N]), - {ok,Pid}; + case logger:get_handler_config(Name) of + {ok,_} -> + %% ct:pal("Process ~p up (~p tries left)",[Name,N]), + {ok,Pid}; + _ -> + wait_for_process_up1(Name, RegName, N-1) + end; undefined -> %% ct:pal("Waiting for process ~p (~p tries left)",[Name,N]), - wait_for_process_up1(Name,N-1) + wait_for_process_up1(Name, RegName, N-1) end. filesync_rep_int() -> @@ -1598,3 +1600,8 @@ filesync_rep_int() -> true -> 5500; false -> ?FILESYNC_REPEAT_INTERVAL + 500 end. + + +file_delete(Log) -> + file:delete(Log). + diff --git a/lib/megaco/doc/src/Makefile b/lib/megaco/doc/src/Makefile index 43704cddf4..72feb9d2b3 100644 --- a/lib/megaco/doc/src/Makefile +++ b/lib/megaco/doc/src/Makefile @@ -114,6 +114,7 @@ clean_man: clean_html: rm -rf $(HTMLDIR)/* + rm -rf $(XMLDIR) imgs: $(IMG_FILES:%=$(HTMLDIR)/%) diff --git a/lib/mnesia/doc/src/Makefile b/lib/mnesia/doc/src/Makefile index da52c69f00..d9647fc081 100644 --- a/lib/mnesia/doc/src/Makefile +++ b/lib/mnesia/doc/src/Makefile @@ -118,6 +118,7 @@ html: gifs $(HTML_REF_MAN_FILE) clean clean_docs: rm -rf $(HTMLDIR)/* + rm -rf $(XMLDIR) rm -f $(MAN3DIR)/* rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo) rm -f errs core *~ diff --git a/lib/mnesia/src/mnesia.erl b/lib/mnesia/src/mnesia.erl index e298904e2a..62202401ed 100644 --- a/lib/mnesia/src/mnesia.erl +++ b/lib/mnesia/src/mnesia.erl @@ -168,6 +168,9 @@ -type snmp_struct() :: [{atom(), snmp_type() | tuple_of(snmp_type())}]. -type snmp_type() :: 'fix_string' | 'string' | 'integer'. -type tuple_of(_T) :: tuple(). +-type config_key() :: extra_db_nodes | dc_dump_limit. +-type config_value() :: [node()] | number(). +-type config_result() :: {ok, config_value()} | {error, term()}. -define(DEFAULT_ACCESS, ?MODULE). @@ -278,7 +281,8 @@ stop() -> Other -> Other end. --spec change_config(Config::atom(), Value::_) -> ok | {error, term()}. +-spec change_config(Config::config_key(), Value::config_value()) -> + config_result(). change_config(extra_db_nodes, Ns) when is_list(Ns) -> mnesia_controller:connect_nodes(Ns); change_config(dc_dump_limit, N) when is_number(N), N > 0 -> diff --git a/lib/observer/doc/src/Makefile b/lib/observer/doc/src/Makefile index 11bfee1bdb..e843772f0b 100644 --- a/lib/observer/doc/src/Makefile +++ b/lib/observer/doc/src/Makefile @@ -105,6 +105,7 @@ html: gifs $(HTML_REF_MAN_FILE) $(ONLY_HTML_FILE:%=$(HTMLDIR)/%) clean clean_docs: rm -rf $(HTMLDIR)/* + rm -rf $(XMLDIR) rm -f $(MAN1DIR)/* rm -f $(MAN3DIR)/* rm -f $(MAN6DIR)/* diff --git a/lib/odbc/doc/src/Makefile b/lib/odbc/doc/src/Makefile index b3f93a7e9c..553db8a9a4 100644 --- a/lib/odbc/doc/src/Makefile +++ b/lib/odbc/doc/src/Makefile @@ -101,6 +101,7 @@ html: gifs $(HTML_REF_MAN_FILE) clean clean_docs: rm -rf $(HTMLDIR)/* + rm -rf $(XMLDIR) rm -f $(MAN3DIR)/* rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo) rm -f errs core *~ diff --git a/lib/os_mon/doc/src/Makefile b/lib/os_mon/doc/src/Makefile index 4aa8879a91..354f8ed26b 100644 --- a/lib/os_mon/doc/src/Makefile +++ b/lib/os_mon/doc/src/Makefile @@ -98,6 +98,7 @@ debug opt: clean clean_docs: rm -rf $(HTMLDIR)/* + rm -rf $(XMLDIR) rm -f $(MAN3DIR)/* rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo) rm -f errs core *~ diff --git a/lib/otp_mibs/doc/src/Makefile b/lib/otp_mibs/doc/src/Makefile index c65e2a8e3c..143d9befb8 100644 --- a/lib/otp_mibs/doc/src/Makefile +++ b/lib/otp_mibs/doc/src/Makefile @@ -93,6 +93,7 @@ debug opt: clean clean_docs: rm -rf $(HTMLDIR)/* + rm -rf $(XMLDIR) rm -f $(MAN3DIR)/* rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo) rm -f errs core *~ diff --git a/lib/parsetools/doc/src/Makefile b/lib/parsetools/doc/src/Makefile index e4cd2c0a76..a40ccd0fe7 100644 --- a/lib/parsetools/doc/src/Makefile +++ b/lib/parsetools/doc/src/Makefile @@ -89,6 +89,7 @@ html: gifs $(HTML_REF_MAN_FILE) clean clean_docs: rm -rf $(HTMLDIR)/* + rm -rf $(XMLDIR) rm -f $(MAN3DIR)/* rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo) rm -f errs core *~ diff --git a/lib/public_key/doc/src/Makefile b/lib/public_key/doc/src/Makefile index f5157fe87a..03467e9783 100644 --- a/lib/public_key/doc/src/Makefile +++ b/lib/public_key/doc/src/Makefile @@ -99,6 +99,7 @@ html: gifs $(HTML_REF_MAN_FILE) clean clean_docs: rm -rf $(HTMLDIR)/* + rm -rf $(XMLDIR) rm -f $(MAN3DIR)/* rm -f $(MAN6DIR)/* rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo) diff --git a/lib/reltool/doc/src/Makefile b/lib/reltool/doc/src/Makefile index e378cdf980..8daafb7a2b 100644 --- a/lib/reltool/doc/src/Makefile +++ b/lib/reltool/doc/src/Makefile @@ -88,6 +88,7 @@ clean clean_docs: fi \ done rm -rf $(HTMLDIR)/* + rm -rf $(XMLDIR) rm -f $(MAN3DIR)/* rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo) rm -f errs core *~ diff --git a/lib/runtime_tools/doc/src/Makefile b/lib/runtime_tools/doc/src/Makefile index b788ef55ff..2399ed51e0 100644 --- a/lib/runtime_tools/doc/src/Makefile +++ b/lib/runtime_tools/doc/src/Makefile @@ -120,6 +120,7 @@ debug opt: clean clean_docs: rm -rf $(HTMLDIR)/* + rm -rf $(XMLDIR) rm -f $(MAN3DIR)/* rm -f $(MAN6DIR)/* rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo) diff --git a/lib/sasl/doc/src/Makefile b/lib/sasl/doc/src/Makefile index baf563ca62..8e1e8b502c 100644 --- a/lib/sasl/doc/src/Makefile +++ b/lib/sasl/doc/src/Makefile @@ -101,6 +101,7 @@ debug opt: clean clean_docs: rm -rf $(HTMLDIR)/* + rm -rf $(XMLDIR) rm -f $(MAN3DIR)/* rm -f $(MAN4DIR)/* rm -f $(MAN6DIR)/* diff --git a/lib/sasl/test/sasl_report_SUITE.erl b/lib/sasl/test/sasl_report_SUITE.erl index 863b765645..a03932133e 100644 --- a/lib/sasl/test/sasl_report_SUITE.erl +++ b/lib/sasl/test/sasl_report_SUITE.erl @@ -21,6 +21,7 @@ -export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, init_per_group/2,end_per_group/2]). -export([gen_server_crash/1, gen_server_crash_unicode/1]). +-export([legacy_gen_server_crash/1, legacy_gen_server_crash_unicode/1]). -export([crash_me/0,start_link/0,init/1,handle_cast/2,terminate/2]). @@ -29,7 +30,10 @@ suite() -> [{ct_hooks,[ts_install_cth]}]. all() -> - [gen_server_crash, gen_server_crash_unicode]. + [gen_server_crash, + gen_server_crash_unicode, + legacy_gen_server_crash, + legacy_gen_server_crash_unicode]. groups() -> []. @@ -52,17 +56,77 @@ gen_server_crash(Config) -> gen_server_crash_unicode(Config) -> gen_server_crash(Config, unicode). +legacy_gen_server_crash(Config) -> + legacy_gen_server_crash(Config,latin1). + +legacy_gen_server_crash_unicode(Config) -> + legacy_gen_server_crash(Config,unicode). + gen_server_crash(Config, Encoding) -> + TC = list_to_atom(lists:concat([?FUNCTION_NAME,"_",Encoding])), + PrivDir = filename:join(?config(priv_dir,Config),?MODULE), + ConfigFileName = filename:join(PrivDir,TC), + KernelLog = filename:join(PrivDir,lists:concat([TC,"_kernel.log"])), + SaslLog = filename:join(PrivDir,lists:concat([TC,"_sasl.log"])), + KernelConfig = [{logger,[{handler,default,logger_std_h, + #{config=>#{type=>{file,KernelLog}}}}]}, + {logger_sasl_compatible,true}], + Modes = [write, {encoding, Encoding}], + SaslConfig = [{sasl_error_logger,{file,SaslLog,Modes}}], + ok = filelib:ensure_dir(SaslLog), + + ok = file:write_file(ConfigFileName ++ ".config", + io_lib:format("[{kernel, ~p},~n{sasl, ~p}].", + [KernelConfig,SaslConfig])), + {ok,Node} = + test_server:start_node( + TC, peer, + [{args, ["-pa ",filename:dirname(code:which(?MODULE)), + " -boot start_sasl -kernel start_timer true " + "-config ",ConfigFileName]}]), + + %% Set depth + ok = rpc:call(Node,logger,update_formatter_config,[default,depth,30]), + ok = rpc:call(Node,logger,update_formatter_config,[sasl,depth,30]), + + %% Make sure remote node logs it's own logs, and current node does + %% not log them. + ok = rpc:call(Node,logger,remove_handler_filter,[default,remote_gl]), + ok = rpc:call(Node,logger,remove_handler_filter,[sasl,remote_gl]), + ok = logger:add_primary_filter(no_remote,{fun(#{meta:=#{pid:=Pid}},_) + when node(Pid)=/=node() -> stop; + (_,_) -> ignore + end,[]}), + ct:log("Local node Logger config:~n~p", + [rpc:call(Node,logger,get_config,[])]), + ct:log("Remote node Logger config:~n~p", + [rpc:call(Node,logger,get_config,[])]), + ct:log("Remote node error_logger handlers: ~p", + [rpc:call(Node,error_logger,which_report_handlers,[])]), + + ok = rpc:call(Node,?MODULE,crash_me,[]), + + test_server:stop_node(Node), + ok = logger:remove_primary_filter(no_remote), + + check_file(KernelLog, utf8, 70000, 150000), + check_file(SaslLog, Encoding, 70000, 150000), + + ok = file:delete(KernelLog), + ok = file:delete(SaslLog), + + ok. + +legacy_gen_server_crash(Config, Encoding) -> StopFilter = {fun(_,_) -> stop end, ok}, logger:add_handler_filter(default,stop_all,StopFilter), + logger:add_handler_filter(sasl,stop_all,StopFilter), logger:add_handler_filter(cth_log_redirect,stop_all,StopFilter), try do_gen_server_crash(Config, Encoding) after - ok = application:unset_env(kernel, logger_sasl_compatible), - ok = application:unset_env(sasl, sasl_error_logger), - ok = application:unset_env(kernel, error_logger_format_depth), logger:remove_handler_filter(default,stop_all), + logger:remove_handler_filter(sasl,stop_all), logger:remove_handler_filter(cth_log_redirect,stop_all) end, ok. @@ -74,22 +138,17 @@ do_gen_server_crash(Config, Encoding) -> SaslLog = filename:join(LogDir, "sasl.log"), ok = filelib:ensure_dir(SaslLog), - application:stop(sasl), Modes = [write, {encoding, Encoding}], - ok = application:set_env(kernel, logger_sasl_compatible, true), - ok = application:set_env(sasl, sasl_error_logger, {file,SaslLog,Modes}, - [{persistent,true}]), application:set_env(kernel, error_logger_format_depth, 30), error_logger:logfile({open,KernelLog}), - application:start(sasl), + error_logger:add_report_handler(sasl_report_file_h,{SaslLog,Modes,all}), ct:log("Logger config:~n~p",[logger:get_config()]), ct:log("error_logger handlers: ~p",[error_logger:which_report_handlers()]), crash_me(), - error_logger:logfile(close), - application:stop(sasl), + error_logger:delete_report_handler(sasl_report_file_h), check_file(KernelLog, utf8, 70000, 150000), check_file(SaslLog, Encoding, 70000, 150000), diff --git a/lib/snmp/doc/src/Makefile b/lib/snmp/doc/src/Makefile index 3ebee792f9..a6a9477b05 100644 --- a/lib/snmp/doc/src/Makefile +++ b/lib/snmp/doc/src/Makefile @@ -140,6 +140,7 @@ clean_man: clean_html: @echo "cleaning html:" rm -rf $(HTMLDIR)/* + rm -rf $(XMLDIR) $(MAN7DIR)/%.7: $(MIBSDIR)/%.mib @echo "processing $*" diff --git a/lib/ssh/doc/src/Makefile b/lib/ssh/doc/src/Makefile index 425322f6ca..77fa356092 100644 --- a/lib/ssh/doc/src/Makefile +++ b/lib/ssh/doc/src/Makefile @@ -119,6 +119,7 @@ html: images $(HTML_REF_MAN_FILE) clean clean_docs: rm -rf $(HTMLDIR)/* + rm -rf $(XMLDIR) rm -f $(MAN3DIR)/* rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo) rm -f $(SPECS_FILES) diff --git a/lib/ssl/doc/src/Makefile b/lib/ssl/doc/src/Makefile index f9128e8e45..d459463322 100644 --- a/lib/ssl/doc/src/Makefile +++ b/lib/ssl/doc/src/Makefile @@ -102,6 +102,7 @@ html: gifs $(HTML_REF_MAN_FILE) clean clean_docs: rm -rf $(HTMLDIR)/* + rm -rf $(XMLDIR) rm -f $(MAN3DIR)/* rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo) rm -f errs core *~ diff --git a/lib/ssl/doc/src/notes.xml b/lib/ssl/doc/src/notes.xml index 917df03b5b..62ec9d0190 100644 --- a/lib/ssl/doc/src/notes.xml +++ b/lib/ssl/doc/src/notes.xml @@ -170,6 +170,35 @@ </section> +<section><title>SSL 8.2.6.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Improve cipher suite handling correcting ECC and TLS-1.2 + requierments. Backport of solution for ERL-641</p> + <p> + Own Id: OTP-15178</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Option keyfile defaults to certfile and should be trumped + with key. This failed for engine keys.</p> + <p> + Own Id: OTP-15193</p> + </item> + </list> + </section> + +</section> + <section><title>SSL 8.2.6</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/ssl/src/ssl_config.erl b/lib/ssl/src/ssl_config.erl index 63c0a416ef..1e6dab9276 100644 --- a/lib/ssl/src/ssl_config.erl +++ b/lib/ssl/src/ssl_config.erl @@ -91,9 +91,9 @@ init_certificates(undefined, #{pem_cache := PemCache} = Config, CertFile, server end; init_certificates(Cert, Config, _, _) -> {ok, Config#{own_certificate => Cert}}. -init_private_key(_, #{algorithm := Alg} = Key, <<>>, _Password, _Client) when Alg == ecdsa; - Alg == rsa; - Alg == dss -> +init_private_key(_, #{algorithm := Alg} = Key, _, _Password, _Client) when Alg == ecdsa; + Alg == rsa; + Alg == dss -> case maps:is_key(engine, Key) andalso maps:is_key(key_id, Key) of true -> Key; diff --git a/lib/ssl/test/ssl_engine_SUITE.erl b/lib/ssl/test/ssl_engine_SUITE.erl index 7277dad012..1423c99dc2 100644 --- a/lib/ssl/test/ssl_engine_SUITE.erl +++ b/lib/ssl/test/ssl_engine_SUITE.erl @@ -117,8 +117,23 @@ private_key(Config) when is_list(Config) -> EngineServerConf = [{key, #{algorithm => rsa, engine => Engine, key_id => ServerKey}} | proplists:delete(key, ServerConf)], + + EngineFileClientConf = [{key, #{algorithm => rsa, + engine => Engine, + key_id => ClientKey}} | + proplists:delete(keyfile, FileClientConf)], + + EngineFileServerConf = [{key, #{algorithm => rsa, + engine => Engine, + key_id => ServerKey}} | + proplists:delete(keyfile, FileServerConf)], + %% Test with engine test_tls_connection(EngineServerConf, EngineClientConf, Config), + + %% Test with engine and present file arugments + test_tls_connection(EngineFileServerConf, EngineFileClientConf, Config), + %% Test that sofware fallback is available test_tls_connection(ServerConf, [{reuse_sessions, false} |ClientConf], Config). diff --git a/lib/stdlib/doc/src/Makefile b/lib/stdlib/doc/src/Makefile index 2b3860b76a..4541b4a463 100644 --- a/lib/stdlib/doc/src/Makefile +++ b/lib/stdlib/doc/src/Makefile @@ -155,6 +155,7 @@ debug opt: clean clean_docs: rm -rf $(HTMLDIR)/* + rm -rf $(XMLDIR) rm -f $(MAN3DIR)/* rm -f $(MAN6DIR)/* rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo) diff --git a/lib/stdlib/src/proc_lib.erl b/lib/stdlib/src/proc_lib.erl index 89a840be2d..d07c62500b 100644 --- a/lib/stdlib/src/proc_lib.erl +++ b/lib/stdlib/src/proc_lib.erl @@ -30,7 +30,7 @@ start/3, start/4, start/5, start_link/3, start_link/4, start_link/5, hibernate/3, init_ack/1, init_ack/2, - init_p/3,init_p/5,format/1,format/2,format/3,report_cb/1, + init_p/3,init_p/5,format/1,format/2,format/3,report_cb/2, initial_call/1, translate_initial_call/1, stop/1, stop/3]). @@ -509,7 +509,7 @@ crash_report(Class, Reason, StartF, Stacktrace) -> report=>[my_info(Class, Reason, StartF, Stacktrace), linked_info(self())]}, #{domain=>[otp,sasl], - report_cb=>fun proc_lib:report_cb/1, + report_cb=>fun proc_lib:report_cb/2, logger_formatter=>#{title=>"CRASH REPORT"}, error_logger=>#{tag=>error_report,type=>crash_report}}). @@ -750,14 +750,15 @@ check(Res) -> Res. %%% Format a generated crash info structure. %%% ----------------------------------------------------------- --spec report_cb(CrashReport) -> {Format,Args} when - CrashReport :: #{label=>{proc_lib,crash},report=>[term()]}, - Format :: io:format(), - Args :: [term()]. -report_cb(#{label:={proc_lib,crash}, - report:=CrashReport}) -> - Depth = error_logger:get_format_depth(), - get_format_and_args(CrashReport, utf8, Depth). +-spec report_cb(CrashReport,FormatOpts) -> unicode:chardata() when + CrashReport :: #{label => {proc_lib,crash}, + report => [term()]}, + FormatOpts :: logger:report_cb_config(). +report_cb(#{label:={proc_lib,crash}, report:=CrashReport}, Extra) -> + Default = #{chars_limit => unlimited, + depth => unlimited, + encoding => latin1}, + do_format(CrashReport, maps:merge(Default,Extra)). -spec format(CrashReport) -> string() when CrashReport :: [term()]. @@ -777,66 +778,47 @@ format(CrashReport, Encoding) -> Depth :: unlimited | pos_integer(). format(CrashReport, Encoding, Depth) -> - {F,A} = get_format_and_args(CrashReport, Encoding, Depth), - lists:flatten(io_lib:format(F,A)). + do_format(CrashReport, #{chars_limit => unlimited, + depth => Depth, + encoding => Encoding}). -get_format_and_args([OwnReport,LinkReport], Encoding, Depth) -> - Extra = {Encoding,Depth}, +do_format([OwnReport,LinkReport], Extra) -> MyIndent = " ", - {OwnFormat,OwnArgs} = format_report(OwnReport, MyIndent, Extra, [], []), - {LinkFormat,LinkArgs} = format_link_report(LinkReport, MyIndent, Extra, [], []), - {" crasher:~n"++OwnFormat++" neighbours:~n"++LinkFormat,OwnArgs++LinkArgs}. + OwnFormat = format_report(OwnReport, MyIndent, Extra), + LinkFormat = format_link_report(LinkReport, MyIndent, Extra), + Str = io_lib:format(" crasher:~n~ts neighbours:~n~ts", + [OwnFormat, LinkFormat]), + lists:flatten(Str). -format_link_report([], _Indent, _Extra, Format, Args) -> - {lists:flatten(lists:reverse(Format)),lists:append(lists:reverse(Args))}; -format_link_report([Link|Reps], Indent, Extra, Format, Args) -> +format_link_report([Link|Reps], Indent, Extra) -> Rep = case Link of {neighbour,Rep0} -> Rep0; _ -> Link end, LinkIndent = [" ",Indent], - {LinkFormat,LinkArgs} = format_report(Rep, LinkIndent, Extra, [], []), - F = "~sneighbour:\n"++LinkFormat, - A = [Indent|LinkArgs], - format_link_report(Reps, Indent, Extra, [F|Format], [A|Args]); -format_link_report(Rep, Indent, Extra, Format, Args) -> - {F,A} = format_report(Rep, Indent, Extra, [], []), - format_link_report([], Indent, Extra, [F|Format],[A|Args]). - -format_report([], _Indent, _Extra, Format, Args) -> - {lists:flatten(lists:reverse(Format)),lists:append(lists:reverse(Args))}; -format_report([Rep|Reps], Indent, Extra, Format, Args) -> - {F,A} = format_rep(Rep, Indent, Extra), - format_report(Reps, Indent, Extra, [F|Format], [A|Args]); -format_report(Rep, Indent, {Enc,unlimited}=Extra, Format, Args) -> - {F,A} = {"~s~"++modifier(Enc)++"p~n", [Indent, Rep]}, - format_report([], Indent, Extra, [F|Format], [A|Args]); -format_report(Rep, Indent, {Enc,Depth}=Extra, Format, Args) -> - {F,A} = {"~s~"++modifier(Enc)++"P~n", [Indent, Rep, Depth]}, - format_report([], Indent, Extra, [F|Format], [A|Args]). - -format_rep({initial_call,InitialCall}, Indent, Extra) -> - format_mfa(Indent, InitialCall, Extra); -format_rep({error_info,{Class,Reason,StackTrace}}, _Indent, Extra) -> - {lists:flatten(format_exception(Class, Reason, StackTrace, Extra)),[]}; -format_rep({Tag,Data}, Indent, Extra) -> - format_tag(Indent, Tag, Data, Extra). - -format_mfa(Indent, {M,F,Args}=StartF, {Enc,_}=Extra) -> - try - A = length(Args), - {lists:flatten([Indent,"initial call: ",atom_to_list(M), - $:,to_string(F, Enc),$/,integer_to_list(A),"\n"]),[]} - catch - error:_ -> - format_tag(Indent, initial_call, StartF, Extra) - end. - -format_tag(Indent, Tag, Data, {Enc,Depth}) -> - {P,Tl} = p(Enc, Depth), - {"~s~p: ~80.18" ++ P ++ "\n", [Indent, Tag, Data|Tl]}. + [Indent,"neighbour:\n",format_report(Rep, LinkIndent, Extra)| + format_link_report(Reps, Indent, Extra)]; +format_link_report(Rep, Indent, Extra) -> + format_report(Rep, Indent, Extra). + +format_report(Rep, Indent, Extra) when is_list(Rep) -> + format_rep(Rep, Indent, Extra); +format_report(Rep, Indent, #{encoding:=Enc,depth:=unlimited}) -> + io_lib:format("~s~"++modifier(Enc)++"p~n", [Indent, Rep]); +format_report(Rep, Indent, #{encoding:=Enc,depth:=Depth}) -> + io_lib:format("~s~"++modifier(Enc)++"P~n", [Indent, Rep, Depth]). + +format_rep([{initial_call,InitialCall}|Rep], Indent, Extra) -> + [format_mfa(Indent, InitialCall, Extra)|format_rep(Rep, Indent, Extra)]; +format_rep([{error_info,{Class,Reason,StackTrace}}|Rep], Indent, Extra) -> + [format_exception(Class, Reason, StackTrace, Extra)| + format_rep(Rep, Indent, Extra)]; +format_rep([{Tag,Data}|Rep], Indent, Extra) -> + [format_tag(Indent, Tag, Data, Extra)|format_rep(Rep, Indent, Extra)]; +format_rep(_, _, _Extra) -> + []. -format_exception(Class, Reason, StackTrace, {Enc,_}=Extra) -> +format_exception(Class, Reason, StackTrace, #{encoding:=Enc}=Extra) -> PF = pp_fun(Extra), StackFun = fun(M, _F, _A) -> (M =:= erl_eval) or (M =:= ?MODULE) end, %% EI = " exception: ", @@ -844,17 +826,37 @@ format_exception(Class, Reason, StackTrace, {Enc,_}=Extra) -> [EI, erl_error:format_exception(1+length(EI), Class, Reason, StackTrace, StackFun, PF, Enc), "\n"]. +format_mfa(Indent, {M,F,Args}=StartF, #{encoding:=Enc}=Extra) -> + try + A = length(Args), + [Indent,"initial call: ",atom_to_list(M),$:,to_string(F, Enc),$/, + integer_to_list(A),"\n"] + catch + error:_ -> + format_tag(Indent, initial_call, StartF, Extra) + end. + to_string(A, latin1) -> io_lib:write_atom_as_latin1(A); to_string(A, _) -> io_lib:write_atom(A). -pp_fun({Enc,Depth}) -> +pp_fun(#{encoding:=Enc,depth:=Depth,chars_limit:=Limit}) -> {P,Tl} = p(Enc, Depth), + Opts = if is_integer(Limit) -> [{chars_limit,Limit}]; + true -> [] + end, fun(Term, I) -> - io_lib:format("~." ++ integer_to_list(I) ++ P, [Term|Tl]) + io_lib:format("~." ++ integer_to_list(I) ++ P, [Term|Tl], Opts) end. +format_tag(Indent, Tag, Data, #{encoding:=Enc,depth:=Depth,chars_limit:=Limit}) -> + {P,Tl} = p(Enc, Depth), + Opts = if is_integer(Limit) -> [{chars_limit,Limit}]; + true -> [] + end, + io_lib:format("~s~p: ~80.18" ++ P ++ "\n", [Indent, Tag, Data|Tl], Opts). + p(Encoding, Depth) -> {Letter, Tl} = case Depth of unlimited -> {"p", []}; diff --git a/lib/syntax_tools/doc/src/Makefile b/lib/syntax_tools/doc/src/Makefile index 797f9c265f..d953287bad 100644 --- a/lib/syntax_tools/doc/src/Makefile +++ b/lib/syntax_tools/doc/src/Makefile @@ -125,6 +125,7 @@ debug opt: clean clean_docs: rm -rf $(HTMLDIR)/* + rm -rf $(XMLDIR) rm -f $(MAN3DIR)/* rm -f $(XML_REF3_FILES) $(XML_CHAPTER_FILES) *.html rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo) diff --git a/lib/tftp/doc/src/Makefile b/lib/tftp/doc/src/Makefile index a2fdcf6325..5d76799e41 100644 --- a/lib/tftp/doc/src/Makefile +++ b/lib/tftp/doc/src/Makefile @@ -103,6 +103,7 @@ pdf: $(TOP_PDF_FILE) html: gifs $(HTML_REF_MAN_FILE) clean clean_docs: clean_html clean_man clean_pdf + rm -rf $(XMLDIR) rm -f errs core *~ man: $(MAN3_FILES) diff --git a/lib/tools/doc/src/Makefile b/lib/tools/doc/src/Makefile index 001c31a443..5ff4fe3113 100644 --- a/lib/tools/doc/src/Makefile +++ b/lib/tools/doc/src/Makefile @@ -120,6 +120,7 @@ debug opt: clean clean_docs: rm -rf $(HTMLDIR)/* + rm -rf $(XMLDIR) rm -f $(MAN3DIR)/* rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo) rm -f $(SPECDIR)/* diff --git a/lib/wx/doc/src/Makefile b/lib/wx/doc/src/Makefile index 70555ae1eb..f66d63f63b 100644 --- a/lib/wx/doc/src/Makefile +++ b/lib/wx/doc/src/Makefile @@ -121,7 +121,8 @@ $(XML_CHAPTER_FILES:%=$(XMLDIR)/%): ../overview.edoc debug opt: clean clean_docs: - rm -rf $(HTMLDIR)/* + rm -rf $(HTMLDIR)/* + rm -rf $(XMLDIR) rm -f $(MAN3DIR)/* rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo) rm -f $(SPECDIR)/* diff --git a/lib/xmerl/doc/src/Makefile b/lib/xmerl/doc/src/Makefile index d87677d0a7..0def492246 100644 --- a/lib/xmerl/doc/src/Makefile +++ b/lib/xmerl/doc/src/Makefile @@ -140,6 +140,7 @@ debug opt: clean clean_docs: rm -rf $(HTMLDIR)/* + rm -rf $(XMLDIR) rm -f $(MAN3DIR)/* rm -f $(MAN6DIR)/* rm -f $(XMERL_XML_FILES) diff --git a/lib/xmerl/src/xmerl_scan.erl b/lib/xmerl/src/xmerl_scan.erl index a1f6ad4e2c..a7538180e6 100644 --- a/lib/xmerl/src/xmerl_scan.erl +++ b/lib/xmerl/src/xmerl_scan.erl @@ -279,7 +279,7 @@ int_file_decl(F, Options,_ExtCharset) -> %% @spec string(Text::list()) -> {xmlElement(),Rest} %% Rest = list() -%% @equiv string(Test, []) +%% @equiv string(Text, []) string(Str) -> string(Str, []). diff --git a/make/otp.mk.in b/make/otp.mk.in index c514a150ca..df29d26833 100644 --- a/make/otp.mk.in +++ b/make/otp.mk.in @@ -87,6 +87,13 @@ AR = @AR@ PERL = @PERL@ LLVM_PROFDATA = @LLVM_PROFDATA@ +MIXED_CYGWIN_VC = @MIXED_CYGWIN_VC@ +MIXED_MSYS_VC = @MIXED_MSYS_VC@ +MIXED_VC = @MIXED_VC@ +MIXED_CYGWIN_MINGW = @MIXED_CYGWIN_MINGW@ +MIXED_CYGWIN = @MIXED_CYGWIN@ +MIXED_MSYS = @MIXED_MSYS@ + BITS64 = @BITS64@ OTP_RELEASE = @OTP_RELEASE@ diff --git a/otp_versions.table b/otp_versions.table index a76577c819..f00494ace5 100644 --- a/otp_versions.table +++ b/otp_versions.table @@ -1,6 +1,9 @@ +OTP-21.0.4 : erts-10.0.4 # asn1-5.0.6 common_test-1.16 compiler-7.2.2 crypto-4.3 debugger-4.2.5 dialyzer-3.3 diameter-2.1.5 edoc-0.9.3 eldap-1.2.4 erl_docgen-0.8 erl_interface-3.10.3 et-1.6.2 eunit-2.3.6 ftp-1.0 hipe-3.18 inets-7.0 jinterface-1.9 kernel-6.0 megaco-3.18.3 mnesia-4.15.4 observer-2.8 odbc-2.12.1 os_mon-2.4.5 otp_mibs-1.2 parsetools-2.1.7 public_key-1.6.1 reltool-0.7.6 runtime_tools-1.13 sasl-3.2 snmp-5.2.11 ssh-4.7 ssl-9.0 stdlib-3.5.1 syntax_tools-2.1.5 tftp-1.0 tools-3.0 wx-1.8.4 xmerl-1.3.17 : +OTP-21.0.3 : erts-10.0.3 # asn1-5.0.6 common_test-1.16 compiler-7.2.2 crypto-4.3 debugger-4.2.5 dialyzer-3.3 diameter-2.1.5 edoc-0.9.3 eldap-1.2.4 erl_docgen-0.8 erl_interface-3.10.3 et-1.6.2 eunit-2.3.6 ftp-1.0 hipe-3.18 inets-7.0 jinterface-1.9 kernel-6.0 megaco-3.18.3 mnesia-4.15.4 observer-2.8 odbc-2.12.1 os_mon-2.4.5 otp_mibs-1.2 parsetools-2.1.7 public_key-1.6.1 reltool-0.7.6 runtime_tools-1.13 sasl-3.2 snmp-5.2.11 ssh-4.7 ssl-9.0 stdlib-3.5.1 syntax_tools-2.1.5 tftp-1.0 tools-3.0 wx-1.8.4 xmerl-1.3.17 : OTP-21.0.2 : compiler-7.2.2 erts-10.0.2 public_key-1.6.1 stdlib-3.5.1 # asn1-5.0.6 common_test-1.16 crypto-4.3 debugger-4.2.5 dialyzer-3.3 diameter-2.1.5 edoc-0.9.3 eldap-1.2.4 erl_docgen-0.8 erl_interface-3.10.3 et-1.6.2 eunit-2.3.6 ftp-1.0 hipe-3.18 inets-7.0 jinterface-1.9 kernel-6.0 megaco-3.18.3 mnesia-4.15.4 observer-2.8 odbc-2.12.1 os_mon-2.4.5 otp_mibs-1.2 parsetools-2.1.7 reltool-0.7.6 runtime_tools-1.13 sasl-3.2 snmp-5.2.11 ssh-4.7 ssl-9.0 syntax_tools-2.1.5 tftp-1.0 tools-3.0 wx-1.8.4 xmerl-1.3.17 : OTP-21.0.1 : compiler-7.2.1 erts-10.0.1 # asn1-5.0.6 common_test-1.16 crypto-4.3 debugger-4.2.5 dialyzer-3.3 diameter-2.1.5 edoc-0.9.3 eldap-1.2.4 erl_docgen-0.8 erl_interface-3.10.3 et-1.6.2 eunit-2.3.6 ftp-1.0 hipe-3.18 inets-7.0 jinterface-1.9 kernel-6.0 megaco-3.18.3 mnesia-4.15.4 observer-2.8 odbc-2.12.1 os_mon-2.4.5 otp_mibs-1.2 parsetools-2.1.7 public_key-1.6 reltool-0.7.6 runtime_tools-1.13 sasl-3.2 snmp-5.2.11 ssh-4.7 ssl-9.0 stdlib-3.5 syntax_tools-2.1.5 tftp-1.0 tools-3.0 wx-1.8.4 xmerl-1.3.17 : OTP-21.0 : asn1-5.0.6 common_test-1.16 compiler-7.2 crypto-4.3 debugger-4.2.5 dialyzer-3.3 diameter-2.1.5 edoc-0.9.3 eldap-1.2.4 erl_docgen-0.8 erl_interface-3.10.3 erts-10.0 et-1.6.2 eunit-2.3.6 ftp-1.0 hipe-3.18 inets-7.0 jinterface-1.9 kernel-6.0 mnesia-4.15.4 observer-2.8 os_mon-2.4.5 otp_mibs-1.2 parsetools-2.1.7 public_key-1.6 reltool-0.7.6 runtime_tools-1.13 sasl-3.2 ssh-4.7 ssl-9.0 stdlib-3.5 syntax_tools-2.1.5 tftp-1.0 tools-3.0 wx-1.8.4 xmerl-1.3.17 # megaco-3.18.3 odbc-2.12.1 snmp-5.2.11 : +OTP-20.3.8.3 : erts-9.3.3.2 ic-4.4.4.2 inets-6.5.2.2 kernel-5.4.3.2 ssl-8.2.6.1 # asn1-5.0.5 common_test-1.15.4 compiler-7.1.5 cosEvent-2.2.2 cosEventDomain-1.2.2 cosFileTransfer-1.2.2 cosNotification-1.2.3 cosProperty-1.2.3 cosTime-1.2.3 cosTransactions-1.3.3 crypto-4.2.2 debugger-4.2.4 dialyzer-3.2.4 diameter-2.1.4 edoc-0.9.2 eldap-1.2.3 erl_docgen-0.7.3 erl_interface-3.10.2.1 et-1.6.1 eunit-2.3.5 hipe-3.17.1 jinterface-1.8.1 megaco-3.18.3 mnesia-4.15.3 observer-2.7 odbc-2.12.1 orber-3.8.4 os_mon-2.4.4 otp_mibs-1.1.2 parsetools-2.1.6 public_key-1.5.2 reltool-0.7.5 runtime_tools-1.12.5 sasl-3.1.2 snmp-5.2.11 ssh-4.6.9.1 stdlib-3.4.5 syntax_tools-2.1.4.1 tools-2.11.2 wx-1.8.3 xmerl-1.3.16 : OTP-20.3.8.2 : erl_interface-3.10.2.1 erts-9.3.3.1 ic-4.4.4.1 kernel-5.4.3.1 # asn1-5.0.5 common_test-1.15.4 compiler-7.1.5 cosEvent-2.2.2 cosEventDomain-1.2.2 cosFileTransfer-1.2.2 cosNotification-1.2.3 cosProperty-1.2.3 cosTime-1.2.3 cosTransactions-1.3.3 crypto-4.2.2 debugger-4.2.4 dialyzer-3.2.4 diameter-2.1.4 edoc-0.9.2 eldap-1.2.3 erl_docgen-0.7.3 et-1.6.1 eunit-2.3.5 hipe-3.17.1 inets-6.5.2.1 jinterface-1.8.1 megaco-3.18.3 mnesia-4.15.3 observer-2.7 odbc-2.12.1 orber-3.8.4 os_mon-2.4.4 otp_mibs-1.1.2 parsetools-2.1.6 public_key-1.5.2 reltool-0.7.5 runtime_tools-1.12.5 sasl-3.1.2 snmp-5.2.11 ssh-4.6.9.1 ssl-8.2.6 stdlib-3.4.5 syntax_tools-2.1.4.1 tools-2.11.2 wx-1.8.3 xmerl-1.3.16 : OTP-20.3.8.1 : inets-6.5.2.1 ssh-4.6.9.1 syntax_tools-2.1.4.1 # asn1-5.0.5 common_test-1.15.4 compiler-7.1.5 cosEvent-2.2.2 cosEventDomain-1.2.2 cosFileTransfer-1.2.2 cosNotification-1.2.3 cosProperty-1.2.3 cosTime-1.2.3 cosTransactions-1.3.3 crypto-4.2.2 debugger-4.2.4 dialyzer-3.2.4 diameter-2.1.4 edoc-0.9.2 eldap-1.2.3 erl_docgen-0.7.3 erl_interface-3.10.2 erts-9.3.3 et-1.6.1 eunit-2.3.5 hipe-3.17.1 ic-4.4.4 jinterface-1.8.1 kernel-5.4.3 megaco-3.18.3 mnesia-4.15.3 observer-2.7 odbc-2.12.1 orber-3.8.4 os_mon-2.4.4 otp_mibs-1.1.2 parsetools-2.1.6 public_key-1.5.2 reltool-0.7.5 runtime_tools-1.12.5 sasl-3.1.2 snmp-5.2.11 ssl-8.2.6 stdlib-3.4.5 tools-2.11.2 wx-1.8.3 xmerl-1.3.16 : OTP-20.3.8 : erts-9.3.3 snmp-5.2.11 # asn1-5.0.5 common_test-1.15.4 compiler-7.1.5 cosEvent-2.2.2 cosEventDomain-1.2.2 cosFileTransfer-1.2.2 cosNotification-1.2.3 cosProperty-1.2.3 cosTime-1.2.3 cosTransactions-1.3.3 crypto-4.2.2 debugger-4.2.4 dialyzer-3.2.4 diameter-2.1.4 edoc-0.9.2 eldap-1.2.3 erl_docgen-0.7.3 erl_interface-3.10.2 et-1.6.1 eunit-2.3.5 hipe-3.17.1 ic-4.4.4 inets-6.5.2 jinterface-1.8.1 kernel-5.4.3 megaco-3.18.3 mnesia-4.15.3 observer-2.7 odbc-2.12.1 orber-3.8.4 os_mon-2.4.4 otp_mibs-1.1.2 parsetools-2.1.6 public_key-1.5.2 reltool-0.7.5 runtime_tools-1.12.5 sasl-3.1.2 ssh-4.6.9 ssl-8.2.6 stdlib-3.4.5 syntax_tools-2.1.4 tools-2.11.2 wx-1.8.3 xmerl-1.3.16 : diff --git a/scripts/build-otp b/scripts/build-otp index c38d2c98de..abf8d5d67f 100755 --- a/scripts/build-otp +++ b/scripts/build-otp @@ -57,7 +57,7 @@ if [ "$1" = "docs" ]; then do_and_log "Linting documentation" make xmllint # The code below prepares this build to be used as a deploy to # github pages for documentation. - if [ "$TRAVIS_PULL_REQUEST" = "false" -a "$TRAVIS_TAG" = "" ]; then + if [ "$TRAVIS_PULL_REQUEST" = "false" -a "$TRAVIS_TAG" = "" -a "$TRAVIS_REPO_SLUG" = "erlang/otp" ]; then set -x rm -rf logs SHA=`git rev-parse --verify HEAD` diff --git a/scripts/bundle-otp b/scripts/bundle-otp index f3ff632b63..0ffe7d8c77 100755 --- a/scripts/bundle-otp +++ b/scripts/bundle-otp @@ -2,6 +2,10 @@ set -e +if [ "$TRAVIS_PULL_REQUEST" = "false" -a "$TRAVIS_REPO_SLUG" != "erlang/otp" ]; then + exit 0 +fi + OTP_META_FILE=$ERL_TOP/${TRAVIS_TAG}-bundle.txt OTP_FILE=$ERL_TOP/${TRAVIS_TAG}-bundle.tar.gz @@ -27,3 +31,5 @@ done cd $ERL_TOP/bundle/ tar czf $OTP_FILE * + +exit 0 diff --git a/system/doc/design_principles/Makefile b/system/doc/design_principles/Makefile index 41d2d1208f..242bf1c9a4 100644 --- a/system/doc/design_principles/Makefile +++ b/system/doc/design_principles/Makefile @@ -108,6 +108,7 @@ debug opt: clean clean_docs: rm -rf $(HTMLDIR) + rm -rf $(XMLDIR) rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo) rm -f errs core *~ diff --git a/system/doc/efficiency_guide/Makefile b/system/doc/efficiency_guide/Makefile index f6ad638853..72bcd2ee73 100644 --- a/system/doc/efficiency_guide/Makefile +++ b/system/doc/efficiency_guide/Makefile @@ -99,6 +99,7 @@ debug opt: clean clean_docs: rm -rf $(HTMLDIR) + rm -rf $(XMLDIR) rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo) rm -f errs core *~ diff --git a/system/doc/embedded/Makefile b/system/doc/embedded/Makefile index 2b09c5b852..396aef276b 100644 --- a/system/doc/embedded/Makefile +++ b/system/doc/embedded/Makefile @@ -87,6 +87,7 @@ debug opt: clean clean_docs: rm -rf $(HTMLDIR) + rm -rf $(XMLDIR) rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo) rm -f errs core *~ diff --git a/system/doc/getting_started/Makefile b/system/doc/getting_started/Makefile index 7b90fe1337..cdf1e121c2 100644 --- a/system/doc/getting_started/Makefile +++ b/system/doc/getting_started/Makefile @@ -86,6 +86,7 @@ debug opt: clean clean_docs: rm -rf $(HTMLDIR) + rm -rf $(XMLDIR) rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo) rm -f errs core *~ diff --git a/system/doc/installation_guide/Makefile b/system/doc/installation_guide/Makefile index 91e7cb2772..4a1335cf31 100644 --- a/system/doc/installation_guide/Makefile +++ b/system/doc/installation_guide/Makefile @@ -113,6 +113,7 @@ debug opt: clean clean_docs: rm -f $(GENERATED_XML_FILES) rm -rf $(HTMLDIR) + rm -rf $(XMLDIR) rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo) rm -f errs core *~ diff --git a/system/doc/oam/Makefile b/system/doc/oam/Makefile index b09ae1aed2..147f56f885 100644 --- a/system/doc/oam/Makefile +++ b/system/doc/oam/Makefile @@ -88,6 +88,7 @@ debug opt: clean clean_docs: rm -rf $(HTMLDIR) + rm -rf $(XMLDIR) rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo) rm -f errs core *~ diff --git a/system/doc/programming_examples/Makefile b/system/doc/programming_examples/Makefile index 2d04e8b5e2..e4737ba069 100644 --- a/system/doc/programming_examples/Makefile +++ b/system/doc/programming_examples/Makefile @@ -85,6 +85,7 @@ debug opt: clean clean_docs: rm -rf $(HTMLDIR) + rm -rf $(XMLDIR) rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo) rm -f errs core *~ diff --git a/system/doc/reference_manual/Makefile b/system/doc/reference_manual/Makefile index 02a7f002ed..d034ad2ff8 100644 --- a/system/doc/reference_manual/Makefile +++ b/system/doc/reference_manual/Makefile @@ -96,6 +96,7 @@ debug opt: clean clean_docs: rm -rf $(HTMLDIR) + rm -rf $(XMLDIR) rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo) rm -f errs core *~ diff --git a/system/doc/system_architecture_intro/Makefile b/system/doc/system_architecture_intro/Makefile index ebfcc3a1c8..eb885a744d 100644 --- a/system/doc/system_architecture_intro/Makefile +++ b/system/doc/system_architecture_intro/Makefile @@ -81,6 +81,7 @@ debug opt: clean clean_docs: rm -rf $(HTMLDIR) + rm -rf $(XMLDIR) rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo) rm -f errs core *~ diff --git a/system/doc/system_principles/Makefile b/system/doc/system_principles/Makefile index bb74125f3a..1979deda4c 100644 --- a/system/doc/system_principles/Makefile +++ b/system/doc/system_principles/Makefile @@ -82,6 +82,7 @@ debug opt: clean clean_docs: rm -rf $(HTMLDIR) + rm -rf $(XMLDIR) rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo) rm -f errs core *~ diff --git a/system/doc/tutorial/Makefile b/system/doc/tutorial/Makefile index 70aba663b5..5867096fc8 100644 --- a/system/doc/tutorial/Makefile +++ b/system/doc/tutorial/Makefile @@ -110,6 +110,7 @@ debug opt: clean clean_docs: rm -rf $(HTMLDIR) + rm -rf $(XMLDIR) rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo) rm -f errs core *~ |