diff options
author | Micael Karlberg <[email protected]> | 2011-09-23 14:10:53 +0200 |
---|---|---|
committer | Micael Karlberg <[email protected]> | 2011-09-23 14:10:53 +0200 |
commit | 524ad34276ef31fc5c306943539e3fe9bd19ad8c (patch) | |
tree | b6d497f9461375b02527bc3d1f10c7a58f3e38e0 /erts | |
parent | 3f9de4601b8539eea14de2d1517f54956e05d03a (diff) | |
parent | 92657321ac647f343c6b88985d66a2d611fd982d (diff) | |
download | otp-524ad34276ef31fc5c306943539e3fe9bd19ad8c.tar.gz otp-524ad34276ef31fc5c306943539e3fe9bd19ad8c.tar.bz2 otp-524ad34276ef31fc5c306943539e3fe9bd19ad8c.zip |
Merge branch 'major' of super:otp into bmk/inets/inets58_integration
Diffstat (limited to 'erts')
42 files changed, 521 insertions, 247 deletions
diff --git a/erts/aclocal.m4 b/erts/aclocal.m4 index 3ebea66d30..27f643921e 100644 --- a/erts/aclocal.m4 +++ b/erts/aclocal.m4 @@ -125,6 +125,9 @@ AC_DEFUN(LM_FIND_EMU_CC, ac_cv_prog_emu_cc, [ AC_TRY_COMPILE([],[ +#ifdef __llvm__ +#error "llvm is currently unable to compile beam_emu.c" +#endif __label__ lbl1; __label__ lbl2; int x = magic(); @@ -140,7 +143,7 @@ lbl2: ],ac_cv_prog_emu_cc=$CC,ac_cv_prog_emu_cc=no) if test $ac_cv_prog_emu_cc = no; then - for ac_progname in emu_cc.sh gcc; do + for ac_progname in emu_cc.sh gcc-4.2 gcc; do IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do @@ -1363,7 +1366,8 @@ case "$GCC-$host_cpu" in ;; esac - +test $enable_ethread_pre_pentium4_compatibility = yes && + AC_DEFINE(ETHR_PRE_PENTIUM4_COMPAT, 1, [Define if you want compatibility with x86 processors before pentium4.]) AC_DEFINE(ETHR_HAVE_ETHREAD_DEFINES, 1, \ [Define if you have all ethread defines]) @@ -1645,11 +1649,11 @@ dnl Freely inspired by AC_TRY_LINK. (Maybe better to create a dnl AC_LANG_JAVA instead...) AC_DEFUN(ERL_TRY_LINK_JAVA, [java_link='$JAVAC conftest.java 1>&AC_FD_CC' -changequote(�, �)dnl +changequote(, )dnl cat > conftest.java <<EOF -�$1� +$1 class conftest { public static void main(String[] args) { - �$2� + $2 ; return; }} EOF changequote([, ])dnl diff --git a/erts/configure.in b/erts/configure.in index 3dbf98b876..88337e79fd 100644 --- a/erts/configure.in +++ b/erts/configure.in @@ -3725,7 +3725,7 @@ case "$erl_xcomp_without_sysroot-$with_ssl" in SSL_RUNTIME_LIBDIR="$rdir/lib" SSL_LIBDIR="$dir/lib" SSL_CRYPTO_LIBNAME=libeay32 - SSL_CRYPTO_LIBNAME=ssleay32 + SSL_SSL_LIBNAME=ssleay32 elif test -f "$dir/lib/openssl.lib"; then SSL_RUNTIME_LIBDIR="$rdir/lib" SSL_LIBDIR="$dir/lib" @@ -3907,7 +3907,7 @@ dnl so it is - be adoptable elif test -f "$with_ssl/lib/libeay32.lib"; then SSL_LIBDIR="$with_ssl/lib" SSL_CRYPTO_LIBNAME=libeay32 - SSL_CRYPTO_LIBNAME=ssleay32 + SSL_SSL_LIBNAME=ssleay32 else # This probably wont work, but that's what the user said, so... SSL_LIBDIR="$with_ssl/lib" diff --git a/erts/doc/src/alt_dist.xml b/erts/doc/src/alt_dist.xml index 36d83a685b..c30e04fce7 100644 --- a/erts/doc/src/alt_dist.xml +++ b/erts/doc/src/alt_dist.xml @@ -377,7 +377,7 @@ ( 1) typedef enum { ( 2) portTypeUnknown, /* An uninitialized port */ ( 3) portTypeListener, /* A listening port/socket */ -( 4) portTypeAcceptor, /* An intermidiate stage when accepting +( 4) portTypeAcceptor, /* An intermediate stage when accepting ( 5) on a listen port */ ( 6) portTypeConnector, /* An intermediate stage when connecting */ ( 7) portTypeCommand, /* A connected open port in command mode */ diff --git a/erts/doc/src/erl_nif.xml b/erts/doc/src/erl_nif.xml index 382e446dce..980fc0cc39 100644 --- a/erts/doc/src/erl_nif.xml +++ b/erts/doc/src/erl_nif.xml @@ -216,14 +216,14 @@ ok <p/> <code type="none"> ERL_NIF_TERM term; - MyStruct* ptr = enif_alloc_resource(my_resource_type, sizeof(MyStruct)); + MyStruct* obj = enif_alloc_resource(my_resource_type, sizeof(MyStruct)); /* initialize struct ... */ - term = enif_make_resource(env, ptr); + term = enif_make_resource(env, obj); if (keep_a_reference_of_our_own) { - /* store 'ptr' in static variable, private data or other resource object */ + /* store 'obj' in static variable, private data or other resource object */ } else { enif_release_resource(obj); diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml index 79dc6838a6..61a1c4a0a0 100644 --- a/erts/doc/src/erlang.xml +++ b/erts/doc/src/erlang.xml @@ -1026,6 +1026,56 @@ b</pre> </desc> </func> <func> + <name>erlang:external_size(Term) -> integer() >= 0</name> + <fsummary>Calculate the maximum size for a term encoded in the Erlang + external term format</fsummary> + <type> + <v>Term = term()</v> + </type> + <desc> + <p>Calculates, without doing the encoding, the maximum byte size for + a term encoded in the Erlang external term format. The following + condition applies always:</p> + <p> + <pre> +> <input>Size1 = byte_size(term_to_binary(Term)),</input> +> <input>Size2 = erlang:external_size(Term),</input> +> <input>true = Size1 =< Size2.</input> +true + </pre> + </p> + <p>This is equivalent to a call to: <code>erlang:external_size(Term, []) + </code></p> + </desc> + </func> + <func> + <name>erlang:external_size(Term, [Option]) -> integer() >= 0</name> + <fsummary>Calculate the maximum size for a term encoded in the Erlang + external term format</fsummary> + <type> + <v>Term = term()</v> + <v>Option = {minor_version, Version}</v> + </type> + <desc> + <p>Calculates, without doing the encoding, the maximum byte size for + a term encoded in the Erlang external term format. The following + condition applies always:</p> + <p> + <pre> +> <input>Size1 = byte_size(term_to_binary(Term, Options)),</input> +> <input>Size2 = erlang:external_size(Term, Options),</input> +> <input>true = Size1 =< Size2.</input> +true + </pre> + </p> + <p>The option <c>{minor_version, Version}</c> specifies how floats + are encoded. See + <seealso marker="#term_to_binary/2">term_to_binary/2</seealso> for + a more detailed description. + </p> + </desc> + </func> + <func> <name>float(Number) -> float()</name> <fsummary>Convert a number to a float</fsummary> <type> @@ -5929,7 +5979,7 @@ true</pre> </item> <tag><c>wordsize</c></tag> <item> - <p>Same as <c>{wordsize, internal}</c></p> + <p>Same as <c>{wordsize, internal}.</c></p> </item> <tag><c>{wordsize, internal}</c></tag> <item> @@ -5938,7 +5988,7 @@ true</pre> and on a pure 64-bit architecture 8 is returned. On a halfword 64-bit emulator, 4 is returned, as the Erlang terms are stored using a virtual wordsize of half the - systems wordsize.</p> + system's wordsize.</p> </item> <tag><c>{wordsize, external}</c></tag> <item> diff --git a/erts/doc/src/erlsrv.xml b/erts/doc/src/erlsrv.xml index 0dfad2a112..919caa9542 100644 --- a/erts/doc/src/erlsrv.xml +++ b/erts/doc/src/erlsrv.xml @@ -273,7 +273,7 @@ </desc> </func> <func> - <name>erlsrv {start | stop | disable | enable} <service-name></name> + <name>erlsrv {start | start_disabled | stop | disable | enable} <service-name></name> <fsummary>Manipulate the current service status.</fsummary> <desc> <p>These commands are only added for convenience, the normal @@ -287,6 +287,21 @@ service actually is stopped. Enabling a service sets it in automatic mode, that is started at boot. This command cannot set the service to manual. </p> + + <p>The <c>start_disabled</c> command operates on a service + regardless of if it's enabled/disabled or started/stopped. It + does this by first enabling it (regardless of if it's enabled + or not), then starting it (if it's not already started) and + then disabling it. The result will be a disabled but started + service, regardless of its earlier state. This is useful for + starting services temporarily during a release upgrade. The + difference between using <c>start_disabled</c> and the + sequence <c>enable</c>, <c>start</c> and <c>disable</c> is + that all other <c>erlsrv</c> commands are locked out during + the sequence of operations in <c>start_disable</c>, making the + operation atomic from an <c>erlsrv</c> user's point of + view.</p> + </desc> </func> <func> diff --git a/erts/doc/src/notes.xml b/erts/doc/src/notes.xml index 3733fb2db9..3e9e6a35f2 100644 --- a/erts/doc/src/notes.xml +++ b/erts/doc/src/notes.xml @@ -4534,7 +4534,7 @@ The race occurred when a process removed a table during termination simultaneously as another process removed the same table via <c>ets:delete/1</c> and a third process - created a table that accidentaly got the same internal + created a table that accidentally got the same internal table index as the table being removed.</p> <p> Own Id: OTP-7349</p> diff --git a/erts/doc/src/start_erl.xml b/erts/doc/src/start_erl.xml index 21cc901f52..6f6930af7e 100644 --- a/erts/doc/src/start_erl.xml +++ b/erts/doc/src/start_erl.xml @@ -69,12 +69,29 @@ <c><![CDATA[erl]]></c> program. Everything <em>after</em><c><![CDATA[++]]></c> is interpreted as options to <c><![CDATA[start_erl]]></c> itself.</item> <tag>-reldir <release root></tag> - <item>Mandatory if the environment variable <c><![CDATA[RELDIR]]></c> is not - specified. Tells start_erl where the root of the - release tree is placed in the file-system - (like <Erlang root>\\releases). The - <c><![CDATA[start_erl.data]]></c> file is expected to be placed in - this directory (if not otherwise specified).</item> + + <item>Mandatory if the environment variable + <c><![CDATA[RELDIR]]></c> is not specified and no + <c>-rootdir</c> option is given. Tells start_erl where the + root of the release tree is placed in the file-system (typically + <Erlang root>\\releases). The + <c><![CDATA[start_erl.data]]></c> file is expected to be + placed in this directory (if not otherwise specified). If + only the <c>-rootdir</c> option is given, the directory is + assumed to be <Erlang root>\\releases.</item> + + <tag>-rootdir <Erlang root directory></tag> + + <item>Mandatory if <c>-reldir</c> is not given and there is + no <c><![CDATA[RELDIR]]></c> in the environment. This + specifies the Erlang installation root directory (under + which the <c>lib</c>, <c>releases</c> and + <c>erts-<Version></c> directories are placed). If only + <c>-reldir</c> (or the environment variable + <c><![CDATA[RELDIR]]></c>) is given, the Erlang root is assumed to + be the directory exactly one level above the release + directory.</item> + <tag>-data <data file name></tag> <item>Optional, specifies another data file than start_erl.data in the <release root>. It is specified relative to the diff --git a/erts/emulator/Makefile.in b/erts/emulator/Makefile.in index 1ecda6bfa2..6cd9be5680 100644 --- a/erts/emulator/Makefile.in +++ b/erts/emulator/Makefile.in @@ -600,11 +600,6 @@ INCLUDES += -I$(ERL_TOP)/erts/etc/vxworks endif ifeq ($(TARGET),win32) -# Usually the same as the default rule, but certain platforms (i.e. win32) mix -# different compilers -$(OBJDIR)/beam_emu.o: beam/beam_emu.c - $(EMU_CC) $(subst -O2, $(GEN_OPT_FLGS), $(CFLAGS)) $(INCLUDES) -c $< -o $@ - $(OBJDIR)/dll_sys.o: sys/$(ERLANG_OSTYPE)/sys.c $(CC) $(CFLAGS) -DERL_RUN_SHARED_LIB=1 $(INCLUDES) -c $< -o $@ @@ -618,6 +613,11 @@ $(OBJDIR)/beam_emu.o: beam/beam_emu.c $(CC) $(subst -O2, $(GEN_OPT_FLGS), $(CFLAGS)) \ -OPT:Olimit=0 -WOPT:lpre=off:spre=off:epre=off \ $(INCLUDES) -c $< -o $@ +else +# Usually the same as the default rule, but certain platforms (e.g. win32) mix +# different compilers +$(OBJDIR)/beam_emu.o: beam/beam_emu.c + $(EMU_CC) $(subst -O2, $(GEN_OPT_FLGS), $(CFLAGS)) $(INCLUDES) -c $< -o $@ endif diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c index afdbd65bb5..4b5b5cbdaa 100644 --- a/erts/emulator/beam/beam_emu.c +++ b/erts/emulator/beam/beam_emu.c @@ -1145,26 +1145,11 @@ void process_main(void) Eterm *tmp_big; /* Temporary buffer for small bignums if !HEAP_ON_C_STACK. */ #endif -#ifndef ERTS_SMP -#if !HALFWORD_HEAP - static Eterm save_reg[ERTS_X_REGS_ALLOCATED]; - /* X registers -- not used directly, but - * through 'reg', because using it directly - * needs two instructions on a SPARC, - * while using it through reg needs only - * one. - */ -#endif /* - * Floating point registers. - */ - static FloatDef freg[MAX_REG]; -#else - /* X regisers and floating point registers are located in + * X registers and floating point registers are located in * scheduler specific data. */ register FloatDef *freg; -#endif /* * For keeping the negative old value of 'reds' when call saving is active. @@ -1201,14 +1186,6 @@ void process_main(void) init_done = 1; goto init_emulator; } -#ifndef ERTS_SMP -#if !HALFWORD_HEAP - reg = save_reg; /* XXX: probably wastes a register on x86 */ -#else - /* Registers need to be heap allocated (correct memory range) for tracing to work */ - reg = erts_alloc(ERTS_ALC_T_BEAM_REGISTER, ERTS_X_REGS_ALLOCATED * sizeof(Eterm)); -#endif -#endif c_p = NULL; reds_used = 0; goto do_schedule1; @@ -1229,10 +1206,8 @@ void process_main(void) #endif ERTS_SMP_REQ_PROC_MAIN_LOCK(c_p); PROCESS_MAIN_CHK_LOCKS(c_p); -#ifdef ERTS_SMP - reg = c_p->scheduler_data->save_reg; - freg = c_p->scheduler_data->freg; -#endif + reg = ERTS_PROC_GET_SCHDATA(c_p)->x_reg_array; + freg = ERTS_PROC_GET_SCHDATA(c_p)->f_reg_array; #if !HEAP_ON_C_STACK tmp_big = ERTS_PROC_GET_SCHDATA(c_p)->beam_emu_tmp_heap; #endif @@ -5151,10 +5126,8 @@ void process_main(void) c_p->def_arg_reg[4] = -neg_o_reds; reg[0] = r(0); c_p = hipe_mode_switch(c_p, cmd, reg); -#ifdef ERTS_SMP - reg = c_p->scheduler_data->save_reg; - freg = c_p->scheduler_data->freg; -#endif + reg = ERTS_PROC_GET_SCHDATA(c_p)->x_reg_array; + freg = ERTS_PROC_GET_SCHDATA(c_p)->f_reg_array; ERL_BITS_RELOAD_STATEP(c_p); neg_o_reds = -c_p->def_arg_reg[4]; FCALLS = c_p->fcalls; diff --git a/erts/emulator/beam/bif.tab b/erts/emulator/beam/bif.tab index b171e99e03..831c0b1ce6 100644 --- a/erts/emulator/beam/bif.tab +++ b/erts/emulator/beam/bif.tab @@ -87,6 +87,8 @@ bif erlang:exit/2 bif 'erl.lang.proc':signal/2 ebif_signal_2 exit_2 bif erlang:external_size/1 bif 'erl.lang.term':external_size/1 ebif_external_size_1 +bif erlang:external_size/2 +bif 'erl.lang.term':external_size/2 ebif_external_size_2 ubif erlang:float/1 ubif 'erl.lang.number':to_float/1 ebif_to_float_1 float_1 bif erlang:float_to_list/1 diff --git a/erts/emulator/beam/erl_bif_trace.c b/erts/emulator/beam/erl_bif_trace.c index 0509e51a6f..fbd8757751 100644 --- a/erts/emulator/beam/erl_bif_trace.c +++ b/erts/emulator/beam/erl_bif_trace.c @@ -679,7 +679,7 @@ trace_3(Process* p, Eterm pid_spec, Eterm how, Eterm list) } else if (tracer != NIL) { tracee_port->tracer_proc = tracer; } - /* matches are not counted for ports since it would violate compability */ + /* matches are not counted for ports since it would violate compatibility */ /* This could be a reason to modify this function or make a new one. */ } } diff --git a/erts/emulator/beam/erl_db.c b/erts/emulator/beam/erl_db.c index 59ef8fc3ea..0327850cb9 100644 --- a/erts/emulator/beam/erl_db.c +++ b/erts/emulator/beam/erl_db.c @@ -3659,9 +3659,6 @@ static Eterm table_info(Process* p, DbTable* tb, Eterm What) ret = am_true; else ret = am_false; - } else if (What == am_atom_put("kept_objects",12)) { - ret = make_small(IS_HASH_TABLE(tb->common.status) - ? db_kept_items_hash(&tb->hash) : 0); } else if (What == am_atom_put("safe_fixed",10)) { #ifdef ERTS_SMP erts_smp_mtx_lock(&tb->common.fixlock); @@ -3703,7 +3700,7 @@ static Eterm table_info(Process* p, DbTable* tb, Eterm What) Eterm* hp; db_calc_stats_hash(&tb->hash, &stats); - hp = HAlloc(p, 1 + 6 + FLOAT_SIZE_OBJECT*3); + hp = HAlloc(p, 1 + 7 + FLOAT_SIZE_OBJECT*3); f.fd = stats.avg_chain_len; avg = make_float(hp); PUT_DOUBLE(f, hp); @@ -3718,10 +3715,11 @@ static Eterm table_info(Process* p, DbTable* tb, Eterm What) std_dev_exp = make_float(hp); PUT_DOUBLE(f, hp); hp += FLOAT_SIZE_OBJECT; - ret = TUPLE6(hp, make_small(erts_smp_atomic_read_nob(&tb->hash.nactive)), + ret = TUPLE7(hp, make_small(erts_smp_atomic_read_nob(&tb->hash.nactive)), avg, std_dev_real, std_dev_exp, make_small(stats.min_chain_len), - make_small(stats.max_chain_len)); + make_small(stats.max_chain_len), + make_small(db_kept_items_hash(&tb->hash))); } else { ret = am_false; diff --git a/erts/emulator/beam/erl_init.c b/erts/emulator/beam/erl_init.c index 286fe9ff1e..8a297cded0 100644 --- a/erts/emulator/beam/erl_init.c +++ b/erts/emulator/beam/erl_init.c @@ -808,10 +808,12 @@ early_init(int *argc, char **argv) /* #if defined(HIPE) hipe_signal_init(); /* must be done very early */ #endif - erl_sys_init(); erl_sys_args(argc, argv); + /* Creates threads on Windows that depend on the arguments, so has to be after erl_sys_args */ + erl_sys_init(); + erts_ets_realloc_always_moves = 0; erts_ets_always_compress = 0; erts_dist_buf_busy_limit = ERTS_DE_BUSY_LIMIT; diff --git a/erts/emulator/beam/erl_nif.c b/erts/emulator/beam/erl_nif.c index ea781a6cd0..f3db3f9326 100644 --- a/erts/emulator/beam/erl_nif.c +++ b/erts/emulator/beam/erl_nif.c @@ -578,7 +578,15 @@ int enif_is_identical(Eterm lhs, Eterm rhs) int enif_compare(Eterm lhs, Eterm rhs) { - return CMP(lhs,rhs); + Sint result = CMP(lhs,rhs); + + if (result < 0) { + return -1; + } else if (result > 0) { + return 1; + } + + return result; } int enif_get_tuple(ErlNifEnv* env, Eterm tpl, int* arity, const Eterm** array) diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c index bbdcf79d00..44d2683fe0 100644 --- a/erts/emulator/beam/erl_process.c +++ b/erts/emulator/beam/erl_process.c @@ -2723,11 +2723,14 @@ erts_init_scheduling(int mrq, int no_schedulers, int no_schedulers_online) esdp->match_pseudo_process = NULL; esdp->ssi = ERTS_SCHED_SLEEP_INFO_IX(ix); esdp->free_process = NULL; -#if HALFWORD_HEAP - /* Registers need to be heap allocated (correct memory range) for tracing to work */ - esdp->save_reg = erts_alloc(ERTS_ALC_T_BEAM_REGISTER, ERTS_X_REGS_ALLOCATED * sizeof(Eterm)); -#endif #endif + esdp->x_reg_array = + erts_alloc_permanent_cache_aligned(ERTS_ALC_T_BEAM_REGISTER, + ERTS_X_REGS_ALLOCATED * + sizeof(Eterm)); + esdp->f_reg_array = + erts_alloc_permanent_cache_aligned(ERTS_ALC_T_BEAM_REGISTER, + MAX_REG * sizeof(FloatDef)); #if !HEAP_ON_C_STACK esdp->num_tmp_heap_used = 0; #endif @@ -5785,10 +5788,13 @@ erts_sched_stat_term(Process *p, int total) void erts_schedule_misc_op(void (*func)(void *), void *arg) { - ErtsRunQueue *rq = erts_get_runq_current(NULL); + ErtsRunQueue *rq; ErtsMiscOpList *molp = misc_op_list_alloc(); + ErtsSchedulerData *esdp = erts_get_scheduler_data(); - if (!rq) { + if (esdp) { + rq = esdp->run_queue; + } else { /* * This can only happen when the sys msg dispatcher * thread schedules misc ops (this happens *very* diff --git a/erts/emulator/beam/erl_process.h b/erts/emulator/beam/erl_process.h index 739aef3130..627f10b142 100644 --- a/erts/emulator/beam/erl_process.h +++ b/erts/emulator/beam/erl_process.h @@ -387,19 +387,15 @@ do { \ } while (0) struct ErtsSchedulerData_ { - -#ifdef ERTS_SMP /* * Keep X registers first (so we get as many low * numbered registers as possible in the same cache * line). */ -#if !HALFWORD_HEAP - Eterm save_reg[ERTS_X_REGS_ALLOCATED]; /* X registers */ -#else - Eterm *save_reg; -#endif - FloatDef freg[MAX_REG]; /* Floating point registers. */ + Eterm* x_reg_array; /* X registers */ + FloatDef* f_reg_array; /* Floating point registers. */ + +#ifdef ERTS_SMP ethr_tid tid; /* Thread id */ struct erl_bits_state erl_bits_state; /* erl_bits.c state */ void *match_pseudo_process; /* erl_db_util.c:db_prog_match() */ diff --git a/erts/emulator/beam/erl_threads.h b/erts/emulator/beam/erl_threads.h index 9b897ffd24..12eaf39ec7 100644 --- a/erts/emulator/beam/erl_threads.h +++ b/erts/emulator/beam/erl_threads.h @@ -990,8 +990,9 @@ erts_mtx_destroy(erts_mtx_t *mtx) "Most likely a bug in pthread implementation."; erts_send_warning_to_logger_str_nogl(warn); } + else #endif - erts_thr_fatal_error(res, "destroy mutex"); + erts_thr_fatal_error(res, "destroy mutex"); } #endif } @@ -1094,8 +1095,9 @@ erts_cnd_destroy(erts_cnd_t *cnd) "Most likely a bug in pthread implementation."; erts_send_warning_to_logger_str_nogl(warn); } + else #endif - erts_thr_fatal_error(res, "destroy condition variable"); + erts_thr_fatal_error(res, "destroy condition variable"); } #endif } @@ -1229,8 +1231,9 @@ erts_rwmtx_destroy(erts_rwmtx_t *rwmtx) "Most likely a bug in pthread implementation."; erts_send_warning_to_logger_str_nogl(warn); } + else #endif - erts_thr_fatal_error(res, "destroy rwmutex"); + erts_thr_fatal_error(res, "destroy rwmutex"); } #endif } @@ -1693,8 +1696,9 @@ erts_spinlock_destroy(erts_spinlock_t *lock) "Most likely a bug in pthread implementation."; erts_send_warning_to_logger_str_nogl(warn); } + else #endif - erts_thr_fatal_error(res, "destroy rwlock"); + erts_thr_fatal_error(res, "destroy rwlock"); } #else (void)lock; @@ -1811,8 +1815,9 @@ erts_rwlock_destroy(erts_rwlock_t *lock) "Most likely a bug in pthread implementation."; erts_send_warning_to_logger_str_nogl(warn); } + else #endif - erts_thr_fatal_error(res, "destroy rwlock"); + erts_thr_fatal_error(res, "destroy rwlock"); } #else (void)lock; diff --git a/erts/emulator/beam/external.c b/erts/emulator/beam/external.c index 1a102f7187..6953e7fe7d 100644 --- a/erts/emulator/beam/external.c +++ b/erts/emulator/beam/external.c @@ -459,6 +459,12 @@ Uint erts_encode_ext_size(Eterm term) + 1 /* VERSION_MAGIC */; } +Uint erts_encode_ext_size_2(Eterm term, unsigned dflags) +{ + return encode_size_struct2(NULL, term, TERM_TO_BINARY_DFLAGS|dflags) + + 1 /* VERSION_MAGIC */; +} + Uint erts_encode_ext_size_ets(Eterm term) { return encode_size_struct2(NULL, term, TERM_TO_BINARY_DFLAGS|DFLAGS_INTERNAL_TAGS); @@ -1262,6 +1268,49 @@ external_size_1(Process* p, Eterm Term) } Eterm +external_size_2(Process* p, Eterm Term, Eterm Flags) +{ + Uint size; + Uint flags = TERM_TO_BINARY_DFLAGS; + + while (is_list(Flags)) { + Eterm arg = CAR(list_val(Flags)); + Eterm* tp; + + if (is_tuple(arg) && *(tp = tuple_val(arg)) == make_arityval(2)) { + if (tp[1] == am_minor_version && is_small(tp[2])) { + switch (signed_val(tp[2])) { + case 0: + break; + case 1: + flags |= DFLAG_NEW_FLOATS; + break; + default: + goto error; + } + } else { + goto error; + } + } else { + error: + BIF_ERROR(p, BADARG); + } + Flags = CDR(list_val(Flags)); + } + if (is_not_nil(Flags)) { + goto error; + } + + size = erts_encode_ext_size_2(Term, flags); + if (IS_USMALL(0, size)) { + BIF_RET(make_small(size)); + } else { + Eterm* hp = HAlloc(p, BIG_UINT_HEAP_SIZE); + BIF_RET(uint_to_big(size, hp)); + } +} + +Eterm erts_term_to_binary(Process* p, Eterm Term, int level, Uint flags) { Uint size; diff --git a/erts/emulator/beam/external.h b/erts/emulator/beam/external.h index d8287b96a4..72fe74baf2 100644 --- a/erts/emulator/beam/external.h +++ b/erts/emulator/beam/external.h @@ -160,6 +160,7 @@ Uint erts_encode_dist_ext_size(Eterm, Uint32, ErtsAtomCacheMap *); void erts_encode_dist_ext(Eterm, byte **, Uint32, ErtsAtomCacheMap *); Uint erts_encode_ext_size(Eterm); +Uint erts_encode_ext_size_2(Eterm, unsigned); Uint erts_encode_ext_size_ets(Eterm); void erts_encode_ext(Eterm, byte **); byte* erts_encode_ext_ets(Eterm, byte *, struct erl_off_heap_header** ext_off_heap); diff --git a/erts/emulator/drivers/common/inet_drv.c b/erts/emulator/drivers/common/inet_drv.c index ebc4469a23..743c01d935 100644 --- a/erts/emulator/drivers/common/inet_drv.c +++ b/erts/emulator/drivers/common/inet_drv.c @@ -7012,7 +7012,7 @@ static int sctp_fill_opts(inet_descriptor* desc, char* buf, int buflen, default: RETURN_ERROR(spec, -EINVAL); /* No more valid options */ } - /* If we get here one result has been succesfully loaded */ + /* If we get here one result has been successfully loaded */ length ++; } if (buflen != 0) RETURN_ERROR(spec, -EINVAL); /* Optparam mismatch */ diff --git a/erts/emulator/drivers/win32/win_efile.c b/erts/emulator/drivers/win32/win_efile.c index 3d59564f7b..931bb196f1 100755 --- a/erts/emulator/drivers/win32/win_efile.c +++ b/erts/emulator/drivers/win32/win_efile.c @@ -127,6 +127,8 @@ static int errno_map(DWORD last_error) { return EBUSY; case ERROR_NO_PROC_SLOTS: return EAGAIN; + case ERROR_CANT_RESOLVE_FILENAME: + return EMLINK; case ERROR_ARENA_TRASHED: case ERROR_INVALID_BLOCK: case ERROR_BAD_ENVIRONMENT: @@ -1405,7 +1407,7 @@ efile_readlink(Efile_error* errInfo, char* name, char* buffer, size_t size) DWORD fileAttributes = GetFileAttributesW(wname); if ((fileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) { BOOLEAN success = 0; - HANDLE h = CreateFileW(wname, GENERIC_READ, 0,NULL, OPEN_EXISTING, 0, NULL); + HANDLE h = CreateFileW(wname, GENERIC_READ, 0,NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); int len; if(h != INVALID_HANDLE_VALUE) { success = pGetFinalPathNameByHandle(h, wbuffer, size,0); @@ -1421,7 +1423,7 @@ efile_readlink(Efile_error* errInfo, char* name, char* buffer, size_t size) if (*wbuffer == L'\\') *wbuffer = L'/'; CloseHandle(h); - } + } FreeLibrary(hModule); if (success) { return 1; diff --git a/erts/emulator/hipe/hipe_mode_switch.c b/erts/emulator/hipe/hipe_mode_switch.c index 0b35dbdf04..e5b8cf8a19 100644 --- a/erts/emulator/hipe/hipe_mode_switch.c +++ b/erts/emulator/hipe/hipe_mode_switch.c @@ -473,7 +473,7 @@ Process *hipe_mode_switch(Process *p, unsigned cmd, Eterm reg[]) p = schedule(p, reds_in - p->fcalls); #ifdef ERTS_SMP p->hipe_smp.have_receive_locks = 0; - reg = p->scheduler_data->save_reg; + reg = p->scheduler_data->x_reg_array; #endif } { diff --git a/erts/emulator/sys/common/erl_poll.c b/erts/emulator/sys/common/erl_poll.c index 81f1c95020..9bd64f5908 100644 --- a/erts/emulator/sys/common/erl_poll.c +++ b/erts/emulator/sys/common/erl_poll.c @@ -405,7 +405,7 @@ woke_up(ErtsPollSet ps) static ERTS_INLINE void wake_poller(ErtsPollSet ps, int interrupted) { - int wake; + int wake = 0; #ifdef ERTS_SMP erts_aint32_t wakeup_state; if (!interrupted) diff --git a/erts/emulator/sys/unix/sys.c b/erts/emulator/sys/unix/sys.c index fd15635168..82d2c64d81 100644 --- a/erts/emulator/sys/unix/sys.c +++ b/erts/emulator/sys/unix/sys.c @@ -527,7 +527,6 @@ erts_sys_pre_init(void) void erl_sys_init(void) { - erts_smp_rwmtx_init(&environ_rwmtx, "environ"); #if !DISABLE_VFORK { int res; @@ -3090,6 +3089,8 @@ erl_sys_args(int* argc, char** argv) { int i, j; + erts_smp_rwmtx_init(&environ_rwmtx, "environ"); + i = 1; ASSERT(argc && argv); @@ -3151,4 +3152,5 @@ erl_sys_args(int* argc, char** argv) argv[j++] = argv[i]; } *argc = j; + } diff --git a/erts/emulator/sys/win32/sys.c b/erts/emulator/sys/win32/sys.c index ce1d376a54..3e151c26d5 100644 --- a/erts/emulator/sys/win32/sys.c +++ b/erts/emulator/sys/win32/sys.c @@ -2772,7 +2772,7 @@ ready_output(ErlDrvData drv_data, ErlDrvEvent ready_event) DEBUGF(("ready_output(%d, 0x%x)\n", drv_data, ready_event)); set_busy_port(dp->port_num, 0); if (!(dp->outbuf)) { - /* Happens because event sometimes get signalled during a succesful + /* Happens because event sometimes get signalled during a successful write... */ return; } @@ -3283,6 +3283,7 @@ erts_sys_pre_init(void) } #endif erts_smp_atomic_init_nob(&sys_misc_mem_sz, 0); + erts_sys_env_init(); } void noinherit_std_handle(DWORD type) @@ -3298,8 +3299,6 @@ void erl_sys_init(void) { HANDLE handle; - erts_sys_env_init(); - noinherit_std_handle(STD_OUTPUT_HANDLE); noinherit_std_handle(STD_INPUT_HANDLE); noinherit_std_handle(STD_ERROR_HANDLE); diff --git a/erts/emulator/test/binary_SUITE.erl b/erts/emulator/test/binary_SUITE.erl index 459dc84565..d9fc876482 100644 --- a/erts/emulator/test/binary_SUITE.erl +++ b/erts/emulator/test/binary_SUITE.erl @@ -441,6 +441,11 @@ terms(Config) when is_list(Config) -> Sz when is_integer(Sz), size(Bin) =< Sz -> ok end, + Bin1 = term_to_binary(Term, [{minor_version, 1}]), + case erlang:external_size(Bin1, [{minor_version, 1}]) of + Sz1 when is_integer(Sz1), size(Bin1) =< Sz1 -> + ok + end, Term = binary_to_term(Bin), Term = binary_to_term(Bin, [safe]), Unaligned = make_unaligned_sub_binary(Bin), @@ -473,7 +478,12 @@ terms_float(Config) when is_list(Config) -> Term = binary_to_term(Bin0), Bin1 = term_to_binary(Term, [{minor_version,1}]), Term = binary_to_term(Bin1), - true = size(Bin1) < size(Bin0) + true = size(Bin1) < size(Bin0), + Size0 = erlang:external_size(Term), + Size00 = erlang:external_size(Term, [{minor_version, 0}]), + Size1 = erlang:external_size(Term, [{minor_version, 1}]), + true = (Size0 =:= Size00), + true = Size1 < Size0 end). external_size(Config) when is_list(Config) -> @@ -489,7 +499,9 @@ external_size(Config) when is_list(Config) -> io:format(" Aligned size: ~p\n", [Sz1]), io:format("Unaligned size: ~p\n", [Sz2]), ?line ?t:fail() - end. + end, + ?line erlang:external_size(Bin) =:= erlang:external_size(Bin, [{minor_version, 1}]), + ?line erlang:external_size(Unaligned) =:= erlang:external_size(Unaligned, [{minor_version, 1}]). external_size_1(Term, Size0, Limit) when Size0 < Limit -> case erlang:external_size(Term) of diff --git a/erts/emulator/test/distribution_SUITE.erl b/erts/emulator/test/distribution_SUITE.erl index 4bebae51cc..e4af5c00a6 100644 --- a/erts/emulator/test/distribution_SUITE.erl +++ b/erts/emulator/test/distribution_SUITE.erl @@ -173,7 +173,7 @@ bulk_sendsend(Terms, BinSize) -> Ratio = if MonitorCount2 == 0 -> MonitorCount1 / 1.0; true -> MonitorCount1 / MonitorCount2 end, - %% A somewhat arbitrary ratio, but hopefully one that will accomodate + %% A somewhat arbitrary ratio, but hopefully one that will accommodate %% a wide range of CPU speeds. true = (Ratio > 8.0), {comment, diff --git a/erts/emulator/test/driver_SUITE.erl b/erts/emulator/test/driver_SUITE.erl index f6cf01ce16..a77ea4f3be 100644 --- a/erts/emulator/test/driver_SUITE.erl +++ b/erts/emulator/test/driver_SUITE.erl @@ -1590,7 +1590,7 @@ otp_6879(Config) when is_list(Config) -> end end, Procs), - %% Also try it when input exeeds default buffer (256 bytes) + %% Also try it when input exceeds default buffer (256 bytes) ?line Data = lists:seq(1, 1000), ?line case open_port({spawn, Drv}, []) of Port when is_port(Port) -> diff --git a/erts/emulator/test/nif_SUITE.erl b/erts/emulator/test/nif_SUITE.erl index 9c31b7f78d..d95789fa6e 100644 --- a/erts/emulator/test/nif_SUITE.erl +++ b/erts/emulator/test/nif_SUITE.erl @@ -281,6 +281,12 @@ types(Config) when is_list(Config) -> end, int_list()), ?line verify_tmpmem(TmpMem), + ?line true = (compare(-1294536544000, -1178704800000) < 0), + ?line true = (compare(-1178704800000, -1294536544000) > 0), + ?line true = (compare(-295147905179352825856, -36893488147419103232) < 0), + ?line true = (compare(-36893488147419103232, -295147905179352825856) > 0), + ?line true = (compare(-29514790517935282585612345678, -36893488147419103232) < 0), + ?line true = (compare(-36893488147419103232, -29514790517935282585612345678) > 0), ok. int_list() -> diff --git a/erts/epmd/src/epmd_srv.c b/erts/epmd/src/epmd_srv.c index 5debae26b6..da575affa1 100644 --- a/erts/epmd/src/epmd_srv.c +++ b/erts/epmd/src/epmd_srv.c @@ -102,7 +102,8 @@ void run(EpmdVars *g) dbg_printf(g,2,"try to initiate listening port %d", g->port); - if (g->addresses != NULL) + if (g->addresses != NULL && /* String contains non-separator characters if: */ + g->addresses[strspn(g->addresses," ,")] != '\000') { char *tmp; char *token; diff --git a/erts/etc/win32/erlsrv/erlsrv_interactive.c b/erts/etc/win32/erlsrv/erlsrv_interactive.c index 13e029b364..4c990a694d 100644 --- a/erts/etc/win32/erlsrv/erlsrv_interactive.c +++ b/erts/etc/win32/erlsrv/erlsrv_interactive.c @@ -135,7 +135,12 @@ void print_last_error(void){ fprintf(stderr,"Error: %s",mes); LocalFree(mes); } - + +static int get_last_error(void) +{ + return (last_error) ? last_error : GetLastError(); +} + static BOOL install_service(void){ SC_HANDLE scm; SC_HANDLE service; @@ -508,7 +513,7 @@ int do_usage(char *arg0){ "\t[{-sn[ame] | -n[ame]} [<nodename>]]\n" "\t[-d[ebugtype] [{new|reuse|console}]]\n" "\t[-ar[gs] [<limited erl arguments>]]\n\n" - "%s {start | stop | disable | enable} <servicename>\n\n" + "%s {start | start_disabled | stop | disable | enable} <servicename>\n\n" "%s remove <servicename>\n\n" "%s rename <servicename> <servicename>\n\n" "%s list [<servicename>]\n\n" @@ -561,6 +566,45 @@ int do_manage(int argc,char **argv){ return 0; } } + if(!_stricmp(action,"start_disabled")){ + if(!enable_service()){ + fprintf(stderr,"%s: Failed to enable service %s.\n", + argv[0],service_name); + print_last_error(); + return 1; + } + if(!start_service() && get_last_error() != ERROR_SERVICE_ALREADY_RUNNING){ + fprintf(stderr,"%s: Failed to start service %s.\n", + argv[0],service_name); + print_last_error(); + goto failure_starting; + } + + if(!wait_service_trans(SERVICE_STOPPED, SERVICE_START_PENDING, + SERVICE_RUNNING, 60)){ + fprintf(stderr,"%s: Failed to start service %s.\n", + argv[0],service_name); + print_last_error(); + goto failure_starting; + } + + if(!disable_service()){ + fprintf(stderr,"%s: Failed to disable service %s.\n", + argv[0],service_name); + print_last_error(); + return 1; + } + printf("%s: Service %s started.\n", + argv[0],service_name); + return 0; + failure_starting: + if(!disable_service()){ + fprintf(stderr,"%s: Failed to disable service %s.\n", + argv[0],service_name); + print_last_error(); + } + return 1; + } if(!_stricmp(action,"stop")){ if(!stop_service()){ fprintf(stderr,"%s: Failed to stop service %s.\n", @@ -841,6 +885,7 @@ int do_add_or_set(int argc, char **argv){ argv[0], service_name); return 0; } + int do_rename(int argc, char **argv){ RegEntry *current = empty_reg_tab(); RegEntry *dummy = empty_reg_tab(); @@ -1129,35 +1174,131 @@ void read_arguments(int *pargc, char ***pargv){ *pargc = argc; *pargv = argv; } + +/* Create a free-for-all ACL to set on the semaphore */ +PACL get_acl(PSECURITY_DESCRIPTOR secdescp) +{ + DWORD acl_length = 0; + PSID auth_users_sidp = NULL; + PACL aclp = NULL; + SID_IDENTIFIER_AUTHORITY ntauth = SECURITY_NT_AUTHORITY; + + if(!InitializeSecurityDescriptor(secdescp, SECURITY_DESCRIPTOR_REVISION)) { + return NULL; + } + + if(!AllocateAndInitializeSid(&ntauth, + 1, + SECURITY_AUTHENTICATED_USER_RID, + 0, 0, 0, 0, 0, 0, 0, + &auth_users_sidp)) { + return NULL; + } + + acl_length = sizeof(ACL) + + sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + + GetLengthSid(auth_users_sidp); + + if((aclp = (PACL) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, acl_length)) == NULL) { + FreeSid(auth_users_sidp); + return NULL; + } + + if(!InitializeAcl(aclp, acl_length, ACL_REVISION)) { + FreeSid(auth_users_sidp); + HeapFree(GetProcessHeap(), 0, aclp); + return NULL; + } + + if(!AddAccessAllowedAce(aclp, ACL_REVISION, SEMAPHORE_ALL_ACCESS, auth_users_sidp)) { + FreeSid(auth_users_sidp); + HeapFree(GetProcessHeap(), 0, aclp); + return NULL; + } + + if(!SetSecurityDescriptorDacl(secdescp, TRUE, aclp, FALSE)) { + FreeSid(auth_users_sidp); + HeapFree(GetProcessHeap(), 0, aclp); + return NULL; + } + return aclp; +} + +static HANDLE lock_semaphore = NULL; + +int take_lock(void) { + SECURITY_ATTRIBUTES attr; + PACL aclp; + SECURITY_DESCRIPTOR secdesc; + + if ((aclp = get_acl(&secdesc)) == NULL) { + return -1; + } + + memset(&attr,0,sizeof(attr)); + attr.nLength = sizeof(attr); + attr.lpSecurityDescriptor = &secdesc; + attr.bInheritHandle = FALSE; + + if ((lock_semaphore = CreateSemaphore(&attr, 1, 1, ERLSRV_INTERACTIVE_GLOBAL_SEMAPHORE)) == NULL) { + return -1; + } + + if (WaitForSingleObject(lock_semaphore,INFINITE) != WAIT_OBJECT_0) { + return -1; + } + + HeapFree(GetProcessHeap(), 0, aclp); + return 0; +} + +void release_lock(void) { + ReleaseSemaphore(lock_semaphore,1,NULL); +} + int interactive_main(int argc, char **argv){ char *action = argv[1]; - + int res; + + if (take_lock() != 0) { + fprintf(stderr,"%s: unable to acquire global lock (%s).\n",argv[0], + ERLSRV_INTERACTIVE_GLOBAL_SEMAPHORE); + return 1; + } + if(!_stricmp(action,"readargs")){ - read_arguments(&argc,&argv); - action = argv[1]; + read_arguments(&argc,&argv); + action = argv[1]; } if(!_stricmp(action,"set") || !_stricmp(action,"add")) - return do_add_or_set(argc,argv); - if(!_stricmp(action,"rename")) - return do_rename(argc,argv); - if(!_stricmp(action,"remove")) - return do_remove(argc,argv); - if(!_stricmp(action,"list")) - return do_list(argc,argv); - if(!_stricmp(action,"start") || - !_stricmp(action,"stop") || - !_stricmp(action,"enable") || - !_stricmp(action,"disable")) - return do_manage(argc,argv); - if(_stricmp(action,"?") && - _stricmp(action,"/?") && - _stricmp(action,"-?") && - *action != 'h' && - *action != 'H') + res = do_add_or_set(argc,argv); + else if(!_stricmp(action,"rename")) + res = do_rename(argc,argv); + else if(!_stricmp(action,"remove")) + res = do_remove(argc,argv); + else if(!_stricmp(action,"list")) + res = do_list(argc,argv); + else if(!_stricmp(action,"start") || + !_stricmp(action,"start_disabled") || + !_stricmp(action,"stop") || + !_stricmp(action,"enable") || + !_stricmp(action,"disable")) + res = do_manage(argc,argv); + else if(_stricmp(action,"?") && + _stricmp(action,"/?") && + _stricmp(action,"-?") && + *action != 'h' && + *action != 'H') { fprintf(stderr,"%s: action %s not implemented.\n",argv[0],action); - do_usage(argv[0]); - return 1; + do_usage(argv[0]); + res = 1; + } else { + do_usage(argv[0]); + res = 0; + } + release_lock(); + return res; } diff --git a/erts/etc/win32/erlsrv/erlsrv_interactive.h b/erts/etc/win32/erlsrv/erlsrv_interactive.h index deacf81899..602da24575 100644 --- a/erts/etc/win32/erlsrv/erlsrv_interactive.h +++ b/erts/etc/win32/erlsrv/erlsrv_interactive.h @@ -19,6 +19,8 @@ #ifndef _ERLSRV_INTERACTIVE_H #define _ERLSRV_INTERACTIVE_H +#define ERLSRV_INTERACTIVE_GLOBAL_SEMAPHORE "{468d6954-e355-415f-968f-d257cb0feef4}" + int interactive_main(int argc, char **argv); #endif /* _ERLSRV_INTERACTIVE_H */ diff --git a/erts/etc/win32/start_erl.c b/erts/etc/win32/start_erl.c index dcf8c8b281..6ca7dd9b99 100644 --- a/erts/etc/win32/start_erl.c +++ b/erts/etc/win32/start_erl.c @@ -44,6 +44,8 @@ char *progname; #endif #define RELEASE_SUBDIR "\\releases" +#define ERTS_SUBDIR_PREFIX "\\erts-" +#define BIN_SUBDIR "\\bin" #define REGISTRY_BASE "Software\\Ericsson\\Erlang\\" #define DEFAULT_DATAFILE "start_erl.data" @@ -101,7 +103,8 @@ void exit_help(char *err) printf("Usage:\n%s\n" " [<erlang options>] ++\n" " [-data <datafile>]\n" - " [-reldir <releasedir>]\n" + " {-rootdir <erlang root directory> | \n" + " -reldir <releasedir>}\n" " [-bootflags <bootflagsfile>]\n" " [-noconfig]\n", progname); @@ -177,8 +180,9 @@ void split_commandline(void) */ char * unquote_optionarg(char *str, char **strp) { - char *newstr = (char *)malloc(strlen(str)+1); /* This one is realloc:ed later */ - int i=0, inquote=0; + char *newstr = (char *)malloc(strlen(str)+1); /* This one is + realloc:ed later */ + int i = 0, inquote = 0; assert(newstr); assert(str); @@ -223,8 +227,8 @@ char * unquote_optionarg(char *str, char **strp) /* - * Parses MyCommandLine and tries to fill in all the required option variables - * (one way or another). + * Parses MyCommandLine and tries to fill in all the required option + * variables (in one way or another). */ void parse_commandline(void) { @@ -237,6 +241,11 @@ void parse_commandline(void) *cmdline++; if( strnicmp(cmdline, "data", 4) == 0) { DataFileName = unquote_optionarg(cmdline+4, &cmdline); + } else if( strnicmp(cmdline, "rootdir", 7) == 0) { + RootDir = unquote_optionarg(cmdline+7, &cmdline); +#ifdef _DEBUG + fprintf(stderr, "RootDir: '%s'\n", RootDir); +#endif } else if( strnicmp(cmdline, "reldir", 6) == 0) { RelDir = unquote_optionarg(cmdline+6, &cmdline); #ifdef _DEBUG @@ -266,8 +275,8 @@ void parse_commandline(void) * Read the data file specified and get the version and release number * from it. * - * This function also construct the correct RegistryKey from the version information - * retrieved. + * This function also construct the correct RegistryKey from the version + * information retrieved. */ void read_datafile(void) { @@ -325,88 +334,6 @@ void read_datafile(void) /* - * Read the registry keys we need - */ -void read_registry_keys(void) -{ - HKEY hReg; - ULONG lLen; - - /* Create the RegistryKey name */ - RegistryKey = (char *) malloc(strlen(REGISTRY_BASE) + - strlen(Version) + 1); - assert(RegistryKey); - sprintf(RegistryKey, REGISTRY_BASE "%s", Version); - - /* We always need to find BinDir */ - if( (RegOpenKeyEx(HKEY_LOCAL_MACHINE, - RegistryKey, - 0, - KEY_READ, - &hReg)) != ERROR_SUCCESS ) { - exit_help("Could not open registry key."); - } - - /* First query size of data */ - if( (RegQueryValueEx(hReg, - "Bindir", - NULL, - NULL, - NULL, - &lLen)) != ERROR_SUCCESS) { - exit_help("Failed to query BinDir of release.\n"); - } - - /* Allocate enough space */ - BinDir = (char *)malloc(lLen+1); - assert(BinDir); - /* Retrieve the value */ - if( (RegQueryValueEx(hReg, - "Bindir", - NULL, - NULL, - (unsigned char *) BinDir, - &lLen)) != ERROR_SUCCESS) { - exit_help("Failed to query BinDir of release (2).\n"); - } - -#ifdef _DEBUG - fprintf(stderr, "Bindir: '%s'\n", BinDir); -#endif - - /* We also need the rootdir, in case we need to build RelDir later */ - - /* First query size of data */ - if( (RegQueryValueEx(hReg, - "Rootdir", - NULL, - NULL, - NULL, - &lLen)) != ERROR_SUCCESS) { - exit_help("Failed to query RootDir of release.\n"); - } - - /* Allocate enough space */ - RootDir = (char *) malloc(lLen+1); - assert(RootDir); - /* Retrieve the value */ - if( (RegQueryValueEx(hReg, - "Rootdir", - NULL, - NULL, - (unsigned char *) RootDir, - &lLen)) != ERROR_SUCCESS) { - exit_help("Failed to query RootDir of release (2).\n"); - } - -#ifdef _DEBUG - fprintf(stderr, "Rootdir: '%s'\n", RootDir); -#endif - - RegCloseKey(hReg); -} - -/* * Read the bootflags. This file contains extra command line options to erl.exe */ void read_bootflags(void) @@ -424,7 +351,8 @@ void read_bootflags(void) exit_help("Need -reldir when -bootflags " "filename has relative path."); } else { - newname = (char *)malloc(strlen(BootFlagsFile)+strlen(RelDir)+strlen(Release)+3); + newname = (char *)malloc(strlen(BootFlagsFile)+ + strlen(RelDir)+strlen(Release)+3); assert(newname); sprintf(newname, "%s\\%s\\%s", RelDir, Release, BootFlagsFile); free(BootFlagsFile); @@ -436,8 +364,6 @@ void read_bootflags(void) fprintf(stderr, "BootFlagsFile: '%s'\n", BootFlagsFile); #endif - - if( (fp=fopen(BootFlagsFile, "rb")) == NULL) { exit_help("Could not open BootFlags file."); } @@ -605,32 +531,49 @@ void complete_options(void) sz = nsz; } if (RelDir == NULL) { - if(DataFileName){ - /* Needs to be absolute for this to work, but we - can try... */ - read_datafile(); - read_registry_keys(); - } else { - /* Impossible to find all data... */ - exit_help("Need either Release directory or an absolute " - "datafile name."); - } - /* Ok, construct our own RelDir from RootDir */ - RelDir = (char *) malloc(strlen(RootDir)+strlen(RELEASE_SUBDIR)+1); - assert(RelDir); - sprintf(RelDir, "%s" RELEASE_SUBDIR, RootDir); + if (!RootDir) { + /* Impossible to find all data... */ + exit_help("Need either Root directory nor Release directory."); + } + /* Ok, construct our own RelDir from RootDir */ + RelDir = (char *) malloc(strlen(RootDir)+strlen(RELEASE_SUBDIR)+1); + assert(RelDir); + sprintf(RelDir, "%s" RELEASE_SUBDIR, RootDir); + read_datafile(); } else { read_datafile(); - read_registry_keys(); } } else { read_datafile(); - read_registry_keys(); } + if( !RootDir ) { + /* Try to construct RootDir from RelDir */ + char *p; + RootDir = malloc(strlen(RelDir)+1); + strcpy(RootDir,RelDir); + p = RootDir+strlen(RootDir)-1; + if (p >= RootDir && (*p == '/' || *p == '\\')) + --p; + while (p >= RootDir && *p != '/' && *p != '\\') + --p; + if (p <= RootDir) { /* Empty RootDir is also an error */ + exit_help("Cannot determine Root directory from " + "Release directory."); + } + *p = '\0'; + } + + + BinDir = (char *) malloc(strlen(RootDir)+strlen(ERTS_SUBDIR_PREFIX)+ + strlen(Version)+strlen(BIN_SUBDIR)+1); + assert(BinDir); + sprintf(BinDir, "%s" ERTS_SUBDIR_PREFIX "%s" BIN_SUBDIR, RootDir, Version); + read_bootflags(); #ifdef _DEBUG fprintf(stderr, "RelDir: '%s'\n", RelDir); + fprintf(stderr, "BinDir: '%s'\n", BinDir); #endif } diff --git a/erts/lib_src/common/erl_misc_utils.c b/erts/lib_src/common/erl_misc_utils.c index 35b148990a..5e94ff19db 100644 --- a/erts/lib_src/common/erl_misc_utils.c +++ b/erts/lib_src/common/erl_misc_utils.c @@ -55,6 +55,12 @@ # ifdef HAVE_UNISTD_H # include <unistd.h> # endif +# if defined(_SC_NPROC_CONF) && !defined(_SC_NPROCESSORS_CONF) +# define _SC_NPROCESSORS_CONF _SC_NPROC_CONF +# endif +# if defined(_SC_NPROC_ONLN) && !defined(_SC_NPROCESSORS_ONLN) +# define _SC_NPROCESSORS_ONLN _SC_NPROC_ONLN +# endif # if (defined(NO_SYSCONF) || !defined(_SC_NPROCESSORS_CONF)) # ifdef HAVE_SYS_SYSCTL_H # include <sys/sysctl.h> diff --git a/erts/lib_src/common/erl_printf.c b/erts/lib_src/common/erl_printf.c index 72d18ab6f1..6aa4569d44 100644 --- a/erts/lib_src/common/erl_printf.c +++ b/erts/lib_src/common/erl_printf.c @@ -108,7 +108,7 @@ write_f_add_cr(void *vfp, char* buf, size_t len) if (PUTC(buf[i], (FILE *) vfp) == EOF) return get_error_result(); } - return 0; + return len; } static int @@ -126,13 +126,14 @@ write_f(void *vfp, char* buf, size_t len) #endif if (FWRITE((void *) buf, sizeof(char), len, (FILE *) vfp) != len) return get_error_result(); - return 0; + return len; } static int write_fd(void *vfdp, char* buf, size_t len) { ssize_t size; + size_t res = len; ASSERT(vfdp); while (len) { @@ -149,7 +150,7 @@ write_fd(void *vfdp, char* buf, size_t len) len -= size; } - return 0; + return res; } static int @@ -160,7 +161,7 @@ write_s(void *vwbufpp, char* bufp, size_t len) ASSERT(len > 0); memcpy((void *) *wbufpp, (void *) bufp, len); *wbufpp += len; - return 0; + return len; } @@ -182,6 +183,7 @@ write_sn(void *vwsnap, char* buf, size_t len) memcpy((void *) wsnap->buf, (void *) buf, sz); wsnap->buf += sz; wsnap->len -= sz; + return sz; } return 0; } @@ -201,7 +203,7 @@ write_ds(void *vdsbufp, char* buf, size_t len) } memcpy((void *) (dsbufp->str + dsbufp->str_len), (void *) buf, len); dsbufp->str_len += len; - return 0; + return len; } int diff --git a/erts/preloaded/src/erl_prim_loader.erl b/erts/preloaded/src/erl_prim_loader.erl index ccfa7978c8..4a72bae105 100644 --- a/erts/preloaded/src/erl_prim_loader.erl +++ b/erts/preloaded/src/erl_prim_loader.erl @@ -396,7 +396,7 @@ handle_timeout(State = #state{loader = inet}, Parent) -> inet_timeout_handler(State, Parent). %%% -------------------------------------------------------- -%%% Functions which handles efile as prim_loader (default). +%%% Functions which handle efile as prim_loader (default). %%% -------------------------------------------------------- %%% Reading many files in parallel is an optimization. @@ -523,7 +523,7 @@ efile_timeout_handler(#state{n_timeouts = N} = State, _Parent) -> end. %%% -------------------------------------------------------- -%%% Functions which handles inet prim_loader +%%% Functions which handle inet prim_loader %%% -------------------------------------------------------- %% diff --git a/erts/preloaded/src/init.erl b/erts/preloaded/src/init.erl index e52c813029..c9c434dea0 100644 --- a/erts/preloaded/src/init.erl +++ b/erts/preloaded/src/init.erl @@ -345,7 +345,7 @@ notify(Pids) -> lists:foreach(fun(Pid) -> Pid ! {init,started} end, Pids). %% Garbage collect all info about initially loaded modules. -%% This information is temporary stored until the code_server +%% This information is temporarily stored until the code_server %% is started. %% We force the garbage collection as the init process holds %% this information during the initialisation of the system and diff --git a/erts/preloaded/src/prim_file.erl b/erts/preloaded/src/prim_file.erl index b18a57bfef..30b7a5246a 100644 --- a/erts/preloaded/src/prim_file.erl +++ b/erts/preloaded/src/prim_file.erl @@ -375,7 +375,7 @@ read(#file_descriptor{module = ?MODULE, data = {Port, _}}, Size) {ok, Data}; {error, enomem} -> %% Garbage collecting here might help if - %% the current processes has some old binaries left. + %% the current processes have some old binaries left. erlang:garbage_collect(), case drv_command(Port, <<?FILE_READ, Size:64>>) of {ok, {0, _Data}} when Size =/= 0 -> @@ -825,7 +825,7 @@ list_dir_int(Port, Dir) -> %% Opens a driver port and converts any problems into {error, emfile}. -%% Returns {ok, Port} when succesful. +%% Returns {ok, Port} when successful. drv_open(Driver, Portopts) -> try erlang:open_port({spawn, Driver}, Portopts) of @@ -945,7 +945,7 @@ append([I | Is], R) when is_list(R) -> append(Is, [I | R]); append([], R) -> R. -%% Converts a list of mode atoms into an mode word for the driver. +%% Converts a list of mode atoms into a mode word for the driver. %% Returns {Mode, Portopts, Setopts} where Portopts is a list of %% options for erlang:open_port/2 and Setopts is a list of %% setopt commands to send to the port, or error Reason upon failure. diff --git a/erts/preloaded/src/prim_zip.erl b/erts/preloaded/src/prim_zip.erl index 6a9856fdad..5dc8e3ca13 100644 --- a/erts/preloaded/src/prim_zip.erl +++ b/erts/preloaded/src/prim_zip.erl @@ -21,7 +21,7 @@ -module(prim_zip). -%% unzipping piecemal +%% unzipping piecemeal -export([ open/1, open/3, diff --git a/erts/test/autoimport_SUITE.erl b/erts/test/autoimport_SUITE.erl index 0e4708e046..71ed5204b1 100644 --- a/erts/test/autoimport_SUITE.erl +++ b/erts/test/autoimport_SUITE.erl @@ -87,10 +87,21 @@ autoimports(Config) when is_list(Config) -> xml(XMLFile) -> {ok,File} = file:open(XMLFile,[read]), + xskip_to_funcs(file:read_line(File),File), DocData = xloop(file:read_line(File),File), + true = DocData =/= [], file:close(File), analyze(DocData). +%% Skip lines up to and including the <funcs> tag. +xskip_to_funcs({ok,Line},File) -> + case re:run(Line,"\\<funcs\\>",[{capture,none}]) of + nomatch -> + xskip_to_funcs(file:read_line(File),File); + match -> + ok + end. + xloop({ok,Line},File) -> case re:run(Line,"\\<name\\>",[{capture,none}]) of nomatch -> diff --git a/erts/test/erlc_SUITE.erl b/erts/test/erlc_SUITE.erl index 62e0e6813d..a9e28672e3 100644 --- a/erts/test/erlc_SUITE.erl +++ b/erts/test/erlc_SUITE.erl @@ -79,7 +79,7 @@ compile_erl(Config) when is_list(Config) -> ?line run(Config, Cmd, FileName, "-Werror", ["compile: warnings being treated as errors\$", - "Warning: function foo/0 is unused\$", + "function foo/0 is unused\$", "_ERROR_"]), %% Check a bad file. @@ -213,13 +213,34 @@ deep_cwd_1(PrivDir) -> arg_overflow(Config) when is_list(Config) -> ?line {SrcDir, _OutDir, Cmd} = get_cmd(Config), ?line FileName = filename:join(SrcDir, "erl_test_ok.erl"), - ?line Args = lists:flatten([ ["-D", integer_to_list(N), "=1 "] || - N <- lists:seq(1,10000) ]), + %% Each -D option will be expanded to three arguments when + %% invoking 'erl'. + ?line NumDOptions = num_d_options(), + ?line Args = lists:flatten([ ["-D", integer_to_list(N, 36), "=1 "] || + N <- lists:seq(1, NumDOptions) ]), ?line run(Config, Cmd, FileName, Args, ["Warning: function foo/0 is unused\$", "_OK_"]), ok. +num_d_options() -> + case {os:type(),os:version()} of + {{win32,_},_} -> + %% The maximum size of a command line in the command + %% shell on Windows is 8191 characters. + %% Each -D option is expanded to "@dv NN 1", i.e. + %% 8 characters. (Numbers up to 1295 can be expressed + %% as two 36-base digits.) + 1000; + {{unix,linux},Version} when Version < {2,6,23} -> + %% On some older 64-bit versions of Linux, the maximum number + %% of arguments is 16383. + %% See: http://www.in-ulm.de/~mascheck/various/argmax/ + 5440; + {_,_} -> + 12000 + end. + erlc() -> case os:find_executable("erlc") of false -> |