diff options
-rw-r--r-- | erts/doc/src/driver_entry.xml | 4 | ||||
-rw-r--r-- | erts/doc/src/notes.xml | 16 | ||||
-rw-r--r-- | erts/emulator/beam/bif.c | 4 | ||||
-rw-r--r-- | erts/emulator/beam/erl_driver.h | 4 | ||||
-rw-r--r-- | erts/emulator/beam/erl_gc.c | 2 | ||||
-rw-r--r-- | erts/emulator/beam/utils.c | 2 | ||||
-rw-r--r-- | erts/emulator/drivers/common/inet_drv.c | 2 | ||||
-rw-r--r-- | lib/common_test/src/ct_hooks.erl | 15 | ||||
-rw-r--r-- | lib/common_test/test/ct_hooks_SUITE.erl | 25 | ||||
-rw-r--r-- | lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_suite_crash_in_cth_SUITE.erl | 50 | ||||
-rw-r--r-- | lib/eunit/src/eunit.erl | 10 | ||||
-rw-r--r-- | lib/eunit/src/eunit_surefire.erl | 14 | ||||
-rw-r--r-- | lib/ssh/doc/src/notes.xml | 14 | ||||
-rw-r--r-- | lib/ssh/src/ssh.appup.src | 40 | ||||
-rw-r--r-- | lib/ssh/src/ssh_cli.erl | 2 | ||||
-rw-r--r-- | lib/ssh/src/ssh_connection_handler.erl | 7 | ||||
-rw-r--r-- | lib/ssh/src/ssh_userreg.erl | 28 | ||||
-rw-r--r-- | lib/ssh/vsn.mk | 2 | ||||
-rw-r--r-- | lib/ssl/doc/src/ssl.xml | 12 | ||||
-rw-r--r-- | lib/ssl/src/ssl.erl | 13 | ||||
-rw-r--r-- | lib/ssl/src/ssl_connection.erl | 4 | ||||
-rw-r--r-- | lib/stdlib/doc/src/unicode.xml | 14 | ||||
-rw-r--r-- | lib/tools/emacs/erlang.el | 13 |
23 files changed, 204 insertions, 93 deletions
diff --git a/erts/doc/src/driver_entry.xml b/erts/doc/src/driver_entry.xml index 7860d83d83..8bdd154cb9 100644 --- a/erts/doc/src/driver_entry.xml +++ b/erts/doc/src/driver_entry.xml @@ -133,7 +133,7 @@ typedef struct erl_drv_entry { int (*control)(ErlDrvData drv_data, unsigned int command, char *buf, int len, char **rbuf, int rlen); /* "ioctl" for drivers - invoked by - port_control/3) */ + port_control/3 */ void (*timeout)(ErlDrvData drv_data); /* Handling of timeout in driver */ void (*outputv)(ErlDrvData drv_data, ErlIOVec *ev); /* called when we have output from erlang @@ -146,7 +146,7 @@ typedef struct erl_drv_entry { before 'stop' can be called */ int (*call)(ErlDrvData drv_data, unsigned int command, char *buf, int len, char **rbuf, int rlen, unsigned int *flags); - /* Works mostly like 'control', a syncronous + /* Works mostly like 'control', a synchronous call into the driver. */ void (*event)(ErlDrvData drv_data, ErlDrvEvent event, ErlDrvEventData event_data); diff --git a/erts/doc/src/notes.xml b/erts/doc/src/notes.xml index e91839572b..f5607945a8 100644 --- a/erts/doc/src/notes.xml +++ b/erts/doc/src/notes.xml @@ -30,6 +30,22 @@ </header> <p>This document describes the changes made to the ERTS application.</p> +<section><title>Erts 5.8.3.2</title> + + <section><title>Known Bugs and Problems</title> + <list> + <item> + <p> + Fix halfword emulator bug in <c>ets:select_delete</c> for + <c>ordered_set</c> that caused emulator to crash.</p> + <p> + Own Id: OTP-9258 Aux Id: seq11836 </p> + </item> + </list> + </section> + +</section> + <section><title>Erts 5.8.3.1</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c index 6b1ce823cb..b3325d635b 100644 --- a/erts/emulator/beam/bif.c +++ b/erts/emulator/beam/bif.c @@ -3360,7 +3360,7 @@ BIF_RETTYPE erts_debug_display_1(BIF_ALIST_1) erts_dsprintf_buf_t *dsbufp = erts_create_tmp_dsbuf(64); pres = erts_dsprintf(dsbufp, "%.*T\n", INT_MAX, BIF_ARG_1); if (pres < 0) - erl_exit(1, "Failed to convert term to string: %d (s)\n", + erl_exit(1, "Failed to convert term to string: %d (%s)\n", -pres, erl_errno_id(-pres)); hp = HAlloc(BIF_P, 2*dsbufp->str_len); /* we need length * 2 heap words */ res = buf_to_intlist(&hp, dsbufp->str, dsbufp->str_len, NIL); @@ -3478,7 +3478,7 @@ term2list_dsprintf(Process *p, Eterm term) erts_dsprintf_buf_t *dsbufp = erts_create_tmp_dsbuf(64); pres = erts_dsprintf(dsbufp, "%T", term); if (pres < 0) - erl_exit(1, "Failed to convert term to list: %d (s)\n", + erl_exit(1, "Failed to convert term to list: %d (%s)\n", -pres, erl_errno_id(-pres)); hp = HAlloc(p, 2*dsbufp->str_len); /* we need length * 2 heap words */ res = buf_to_intlist(&hp, dsbufp->str, dsbufp->str_len, NIL); diff --git a/erts/emulator/beam/erl_driver.h b/erts/emulator/beam/erl_driver.h index 3c0eade0d8..069b71ab0d 100644 --- a/erts/emulator/beam/erl_driver.h +++ b/erts/emulator/beam/erl_driver.h @@ -294,7 +294,7 @@ typedef struct erl_drv_entry { int (*control)(ErlDrvData drv_data, unsigned int command, char *buf, int len, char **rbuf, int rlen); /* "ioctl" for drivers - invoked by - port_control/3) */ + port_control/3 */ void (*timeout)(ErlDrvData drv_data); /* Handling of timeout in driver */ void (*outputv)(ErlDrvData drv_data, ErlIOVec *ev); /* called when we have output from erlang @@ -307,7 +307,7 @@ typedef struct erl_drv_entry { before 'stop' can be called */ int (*call)(ErlDrvData drv_data, unsigned int command, char *buf, int len, char **rbuf, int rlen, unsigned int *flags); - /* Works mostly like 'control', a syncronous + /* Works mostly like 'control', a synchronous call into the driver. */ void (*event)(ErlDrvData drv_data, ErlDrvEvent event, ErlDrvEventData event_data); diff --git a/erts/emulator/beam/erl_gc.c b/erts/emulator/beam/erl_gc.c index c30d67ac88..5edcd667e7 100644 --- a/erts/emulator/beam/erl_gc.c +++ b/erts/emulator/beam/erl_gc.c @@ -215,7 +215,7 @@ erts_next_heap_size(Uint size, Uint offset) low = mid + 1; } } - erl_exit(1, "no next heap size found: %d, offset %d\n", size, offset); + erl_exit(1, "no next heap size found: %lu, offset %lu\n", (unsigned long)size, (unsigned long)offset); } return 0; } diff --git a/erts/emulator/beam/utils.c b/erts/emulator/beam/utils.c index f531d1430b..6b4f3b3b36 100644 --- a/erts/emulator/beam/utils.c +++ b/erts/emulator/beam/utils.c @@ -2705,7 +2705,7 @@ term_array: /* arrays in 'aa' and 'bb', length in 'i' */ while (--i) { a = *aa++; b = *bb++; - if (a != b) { + if (!is_same(a,a_base, b,b_base)) { if (is_atom(a) && is_atom(b)) { if ((j = cmp_atoms(a, b)) != 0) { goto not_equal; diff --git a/erts/emulator/drivers/common/inet_drv.c b/erts/emulator/drivers/common/inet_drv.c index 59f4cfb9b4..aec456151c 100644 --- a/erts/emulator/drivers/common/inet_drv.c +++ b/erts/emulator/drivers/common/inet_drv.c @@ -490,7 +490,6 @@ static int my_strncasecmp(const char *s1, const char *s2, size_t n) #define TCP_REQ_RECV 42 #define TCP_REQ_UNRECV 43 #define TCP_REQ_SHUTDOWN 44 -#define TCP_REQ_MULTI_OP 45 /* UDP and SCTP requests */ #define PACKET_REQ_RECV 60 /* Common for UDP and SCTP */ #define SCTP_REQ_LISTEN 61 /* Different from TCP; not for UDP */ @@ -1763,7 +1762,6 @@ send_async_error(ErlDrvPort port, ErlDrvTermData Port, int Ref, LOAD_INT_CNT + 2*LOAD_TUPLE_CNT]; int i = 0; - i = 0; i = LOAD_ATOM(spec, i, am_inet_async); i = LOAD_PORT(spec, i, Port); i = LOAD_INT(spec, i, Ref); diff --git a/lib/common_test/src/ct_hooks.erl b/lib/common_test/src/ct_hooks.erl index 5eddefffce..984e04b90f 100644 --- a/lib/common_test/src/ct_hooks.erl +++ b/lib/common_test/src/ct_hooks.erl @@ -122,11 +122,11 @@ end_tc(_Mod, TC, Config, Result, _Return) -> call(fun call_generic/3, Result, [post_end_per_testcase, TC, Config], '$ct_no_change'). -on_tc_skip(How, {_Suite, Case, Reason}) -> - call(fun call_cleanup/3, {How, Reason}, [on_tc_skip, Case]). +on_tc_skip(How, {Suite, Case, Reason}) -> + call(fun call_cleanup/3, {How, Reason}, [on_tc_skip, Suite, Case]). -on_tc_fail(_How, {_Suite, Case, Reason}) -> - call(fun call_cleanup/3, Reason, [on_tc_fail, Case]). +on_tc_fail(_How, {Suite, Case, Reason}) -> + call(fun call_cleanup/3, Reason, [on_tc_fail, Suite, Case]). %% ------------------------------------------------------------------------- %% Internal Functions @@ -145,7 +145,7 @@ call_terminate({Mod, State}, _, _) -> catch_apply(Mod,terminate,[State], ok), {[],{Mod,State}}. -call_cleanup({Mod, State}, Reason, [Function | Args]) -> +call_cleanup({Mod, State}, Reason, [Function, _Suite | Args]) -> NewState = catch_apply(Mod,Function, Args ++ [Reason, State], State), {Reason, {Mod, NewState}}. @@ -229,6 +229,11 @@ scope([post_init_per_suite, SuiteName|_]) -> scope(init) -> none. +terminate_if_scope_ends(HookId, [on_tc_skip,_Suite,{end_per_group,Name}], + Hooks) -> + terminate_if_scope_ends(HookId, [post_end_per_group, Name], Hooks); +terminate_if_scope_ends(HookId, [on_tc_skip,Suite,end_per_suite], Hooks) -> + terminate_if_scope_ends(HookId, [post_end_per_suite, Suite], Hooks); terminate_if_scope_ends(HookId, [Function,Tag|T], Hooks) when T =/= [] -> terminate_if_scope_ends(HookId,[Function,Tag],Hooks); terminate_if_scope_ends(HookId, Function, Hooks) -> diff --git a/lib/common_test/test/ct_hooks_SUITE.erl b/lib/common_test/test/ct_hooks_SUITE.erl index be1c02f163..8574d7aabc 100644 --- a/lib/common_test/test/ct_hooks_SUITE.erl +++ b/lib/common_test/test/ct_hooks_SUITE.erl @@ -79,7 +79,8 @@ all(suite) -> scope_per_suite_cth, scope_per_group_cth, scope_suite_cth, scope_per_suite_state_cth, scope_per_group_state_cth, scope_suite_state_cth, - fail_pre_suite_cth, fail_post_suite_cth, skip_pre_suite_cth, + fail_pre_suite_cth, double_fail_pre_suite_cth, + fail_post_suite_cth, skip_pre_suite_cth, skip_post_suite_cth, recover_post_suite_cth, update_config_cth, state_update_cth, options_cth, same_id_cth, fail_n_skip_with_minimal_cth @@ -167,6 +168,11 @@ fail_pre_suite_cth(Config) when is_list(Config) -> do_test(fail_pre_suite_cth, "ct_cth_empty_SUITE.erl", [fail_pre_suite_cth],Config). +double_fail_pre_suite_cth(Config) when is_list(Config) -> + do_test(double_fail_pre_suite_cth, "{ct_scope_suite_crash_in_cth_SUITE.erl," + "ct_scope_suite_cth_SUITE.erl}", + [],Config). + fail_post_suite_cth(Config) when is_list(Config) -> do_test(fail_post_suite_cth, "ct_cth_empty_SUITE.erl", [fail_post_suite_cth],Config). @@ -646,6 +652,23 @@ test_events(fail_pre_suite_cth) -> {?eh,stop_logging,[]} ]; +test_events(double_fail_pre_suite_cth) -> + [ + {?eh,start_logging,{'DEF','RUNDIR'}}, + {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}}, + {?eh,tc_start,{'_',init_per_suite}}, + {?eh,cth,{'_',init,['_',[]]}}, + {?eh,cth,{'_',pre_init_per_suite,['_','$proplist',[]]}}, + {?eh,cth,{'_',post_init_per_suite,['_','$proplist', + {fail,"Test failure"},[]]}}, + {?eh,cth, {empty_cth,terminate,[[]]}}, + + {?eh,tc_start,{'_',init_per_suite}}, + {?eh,cth,{'_',init,['_',[]]}}, + {?eh,cth, {empty_cth,terminate,[[]]}}, + {?eh,stop_logging,[]} + ]; + test_events(fail_post_suite_cth) -> [ {?eh,start_logging,{'DEF','RUNDIR'}}, diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_suite_crash_in_cth_SUITE.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_suite_crash_in_cth_SUITE.erl new file mode 100644 index 0000000000..5aa6b0132d --- /dev/null +++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_suite_crash_in_cth_SUITE.erl @@ -0,0 +1,50 @@ +%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+-module(ct_scope_suite_crash_in_cth_SUITE).
+
+-suite_defaults([{timetrap, {minutes, 10}}]).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-include("ct.hrl").
+
+%% Test server callback functions
+suite() ->
+ [{ct_hooks,[fail_pre_suite_cth]}].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_testcase(_TestCase, Config) ->
+ Config.
+
+end_per_testcase(_TestCase, _Config) ->
+ ok.
+
+all() ->
+ [test_case].
+
+%% Test cases starts here.
+test_case(Config) when is_list(Config) ->
+ ok.
diff --git a/lib/eunit/src/eunit.erl b/lib/eunit/src/eunit.erl index 4a86a108cf..da35c5c2ec 100644 --- a/lib/eunit/src/eunit.erl +++ b/lib/eunit/src/eunit.erl @@ -157,6 +157,7 @@ test_run(Reference, Listeners) -> receive {done, Reference} -> cast(Listeners, {stop, Reference, self()}), + wait_until_listeners_have_terminated(Listeners), receive {result, Reference, Result} -> Result @@ -169,6 +170,15 @@ cast([P | Ps], Msg) -> cast([], _Msg) -> ok. +wait_until_listeners_have_terminated([P | Ps]) -> + MRef = erlang:monitor(process, P), + receive + {'DOWN', MRef, process, P, _} -> + wait_until_listeners_have_terminated(Ps) + end; +wait_until_listeners_have_terminated([]) -> + ok. + %% TODO: functions that run tests on a given node, not a given server %% TODO: maybe some functions could check for a globally registered server? %% TODO: some synchronous but completely quiet interface function diff --git a/lib/eunit/src/eunit_surefire.erl b/lib/eunit/src/eunit_surefire.erl index f289cd724a..dfb08c90b2 100644 --- a/lib/eunit/src/eunit_surefire.erl +++ b/lib/eunit/src/eunit_surefire.erl @@ -100,16 +100,10 @@ terminate({ok, _Data}, St) -> XmlDir = St#state.xmldir, write_report(TestSuite, XmlDir), ok; -terminate({error, Reason}, _St) -> - io:fwrite("Internal error: ~P.\n", [Reason, 25]), - sync_end(error). - -sync_end(Result) -> - receive - {stop, Reference, ReplyTo} -> - ReplyTo ! {result, Reference, Result}, - ok - end. +terminate({error, _Reason}, _St) -> + %% Don't report any errors here, since eunit_tty takes care of that. + %% Just terminate. + ok. handle_begin(group, Data, St) -> NewId = proplists:get_value(id, Data), diff --git a/lib/ssh/doc/src/notes.xml b/lib/ssh/doc/src/notes.xml index 224b9d4af7..4f546a37ed 100644 --- a/lib/ssh/doc/src/notes.xml +++ b/lib/ssh/doc/src/notes.xml @@ -29,6 +29,20 @@ <file>notes.xml</file> </header> +<section><title>Ssh 2.0.6</title> + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + A memory leak has been fixed. I.e. per terminated connection the size of + a pid and the length of a user name string was not cleared.</p> + <p> + Own Id: OTP-9232</p> + </item> + </list> + </section> +</section> + <section><title>Ssh 2.0.5</title> <section><title>Improvements and New Features</title> <list> diff --git a/lib/ssh/src/ssh.appup.src b/lib/ssh/src/ssh.appup.src index 9be8c3c7d5..37f24e2463 100644 --- a/lib/ssh/src/ssh.appup.src +++ b/lib/ssh/src/ssh.appup.src @@ -19,44 +19,12 @@ {"%VSN%", [ - {"2.0.4", [{load_module, ssh_bits, soft_purge, soft_purge, []}, - {load_module, ssh_connection_handler, soft_purge, soft_purge, []}]}, - {"2.0.3", [{load_module, ssh_bits, soft_purge, soft_purge, []}, - {load_module, ssh_connection_handler, soft_purge, soft_purge, []}, - {load_module, ssh_file, soft_purge, soft_purge, []}, - {load_module, ssh, soft_purge, soft_purge, []}, - {load_module, ssh_rsa, soft_purge, soft_purge, []}, - {load_module, ssh_acceptor, soft_purge, soft_purge, []}, - {load_module, ssh_transport, soft_purge, soft_purge, []}, - {load_module, ssh_connection_manager, soft_purge, soft_purge, []}]}, - {"2.0.2", [{load_module, ssh_bits, soft_purge, soft_purge, []}, - {load_module, ssh_connection_handler, soft_purge, soft_purge, []}, - {load_module, ssh_file, soft_purge, soft_purge, []}, - {load_module, ssh, soft_purge, soft_purge, []}, - {load_module, ssh_rsa, soft_purge, soft_purge, []}, - {load_module, ssh_acceptor, soft_purge, soft_purge, []}, - {load_module, ssh_transport, soft_purge, soft_purge, []}, - {load_module, ssh_connection_manager, soft_purge, soft_purge, []}]} + {"2.0.5", [{load_module, ssh_userreg, soft_purge, soft_purge, []}, + {load_module, ssh_connection_handler, soft_purge, soft_purge, [ssh_userreg]}]} ], [ - {"2.0.4", [{load_module, ssh_bits, soft_purge, soft_purge, []}, - {load_module, ssh_connection_handler, soft_purge, soft_purge, []}]}, - {"2.0.3", [{load_module, ssh_bits, soft_purge, soft_purge, []}, - {load_module, ssh_connection_handler, soft_purge, soft_purge, []}, - {load_module, ssh_file, soft_purge, soft_purge, []}, - {load_module, ssh, soft_purge, soft_purge, []}, - {load_module, ssh_rsa, soft_purge, soft_purge, []}, - {load_module, ssh_acceptor, soft_purge, soft_purge, []}, - {load_module, ssh_transport, soft_purge, soft_purge, []}, - {load_module, ssh_connection_manager, soft_purge, soft_purge, []}]}, - {"2.0.2", [{load_module, ssh_bits, soft_purge, soft_purge, []}, - {load_module, ssh_connection_handler, soft_purge, soft_purge, []}, - {load_module, ssh_file, soft_purge, soft_purge, []}, - {load_module, ssh, soft_purge, soft_purge, []}, - {load_module, ssh_rsa, soft_purge, soft_purge, []}, - {load_module, ssh_acceptor, soft_purge, soft_purge, []}, - {load_module, ssh_transport, soft_purge, soft_purge, []}, - {load_module, ssh_connection_manager, soft_purge, soft_purge, []}]} + {"2.0.5", [{load_module, ssh_userreg, soft_purge, soft_purge, []}, + {load_module, ssh_connection_handler, soft_purge, soft_purge, [ssh_userreg]}]} ] }. diff --git a/lib/ssh/src/ssh_cli.erl b/lib/ssh/src/ssh_cli.erl index cb78acb84c..781e01b9d1 100644 --- a/lib/ssh/src/ssh_cli.erl +++ b/lib/ssh/src/ssh_cli.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2005-2010. All Rights Reserved. +%% Copyright Ericsson AB 2005-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in diff --git a/lib/ssh/src/ssh_connection_handler.erl b/lib/ssh/src/ssh_connection_handler.erl index 2d82e6d77d..3193be2510 100644 --- a/lib/ssh/src/ssh_connection_handler.erl +++ b/lib/ssh/src/ssh_connection_handler.erl @@ -578,7 +578,9 @@ handle_info({CloseTag, _Socket}, _StateName, %% Reason. The return value is ignored. %%-------------------------------------------------------------------- terminate(normal, _, #state{transport_cb = Transport, - socket = Socket}) -> + socket = Socket, + manager = Pid}) -> + (catch ssh_userreg:delete_user(Pid)), (catch Transport:close(Socket)), ok; @@ -810,7 +812,7 @@ handle_disconnect(#ssh_msg_disconnect{} = Msg, #state{ssh_params = Ssh0, manager = Pid} = State) -> {SshPacket, Ssh} = ssh_transport:ssh_packet(Msg, Ssh0), try - send_msg(SshPacket, State), + send_msg(SshPacket, State), ssh_connection_manager:event(Pid, Msg) catch exit:{noproc, _Reason} -> @@ -822,6 +824,7 @@ handle_disconnect(#ssh_msg_disconnect{} = Msg, [Msg, Exit]), error_logger:info_report(Report) end, + (catch ssh_userreg:delete_user(Pid)), {stop, normal, State#state{ssh_params = Ssh}}. counterpart_versions(NumVsn, StrVsn, #ssh{role = server} = Ssh) -> diff --git a/lib/ssh/src/ssh_userreg.erl b/lib/ssh/src/ssh_userreg.erl index 33c801f490..f901461aea 100644 --- a/lib/ssh/src/ssh_userreg.erl +++ b/lib/ssh/src/ssh_userreg.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -25,11 +25,18 @@ -behaviour(gen_server). %% API --export([start_link/0, register_user/2, lookup_user/1]). +-export([start_link/0, + register_user/2, + lookup_user/1, + delete_user/1]). %% gen_server callbacks --export([init/1, handle_call/3, handle_cast/2, handle_info/2, - terminate/2, code_change/3]). +-export([init/1, + handle_call/3, + handle_cast/2, + handle_info/2, + terminate/2, + code_change/3]). -record(state, {user_db = []}). @@ -46,6 +53,9 @@ start_link() -> register_user(User, Cm) -> gen_server:cast(?MODULE, {register, {User, Cm}}). +delete_user(Cm) -> + gen_server:cast(?MODULE, {delete, Cm}). + lookup_user(Cm) -> gen_server:call(?MODULE, {get_user, Cm}, infinity). @@ -82,9 +92,10 @@ handle_call({get_user, Cm}, _From, #state{user_db = Db} = State) -> %% {stop, Reason, State} %% Description: Handling cast messages %%-------------------------------------------------------------------- -handle_cast({register, UserCm}, State0) -> - State = insert(UserCm, State0), - {noreply, State}. +handle_cast({register, UserCm}, State) -> + {noreply, insert(UserCm, State)}; +handle_cast({delete, UserCm}, State) -> + {noreply, delete(UserCm, State)}. %%-------------------------------------------------------------------- %% Function: handle_info(Info, State) -> {noreply, State} | @@ -118,6 +129,9 @@ code_change(_OldVsn, State, _Extra) -> insert({User, Cm}, #state{user_db = Db} = State) -> State#state{user_db = [{User, Cm} | Db]}. +delete(Cm, #state{user_db = Db} = State) -> + State#state{user_db = lists:keydelete(Cm, 2, Db)}. + lookup(_, []) -> undefined; lookup(Cm, [{User, Cm} | _Rest]) -> diff --git a/lib/ssh/vsn.mk b/lib/ssh/vsn.mk index 8c9f671fd5..d0861b3ddc 100644 --- a/lib/ssh/vsn.mk +++ b/lib/ssh/vsn.mk @@ -1,5 +1,5 @@ #-*-makefile-*- ; force emacs to enter makefile-mode -SSH_VSN = 2.0.5 +SSH_VSN = 2.0.6 APP_VSN = "ssh-$(SSH_VSN)" diff --git a/lib/ssl/doc/src/ssl.xml b/lib/ssl/doc/src/ssl.xml index 60ea4d547f..0da6bbee5b 100644 --- a/lib/ssl/doc/src/ssl.xml +++ b/lib/ssl/doc/src/ssl.xml @@ -53,13 +53,11 @@ <p>The following data types are used in the functions below: </p> - <p><c>boolean() = true | false</c></p> - - <p><c>property() = atom()</c></p> - + <p><c>boolean() = true | false</c></p> + <p><c>option() = socketoption() | ssloption() | transportoption()</c></p> - <p><c>socketoption() = [{property(), term()}] - defaults to + <p><c>socketoption() = proplists:property() - The default socket options are [{mode,list},{packet, 0},{header, 0},{active, true}]. </c></p> @@ -488,7 +486,7 @@ fun(OtpCert :: #'OTPCertificate'{}, Event :: {bad_cert, Reason :: atom()} | <fsummary>Get the value of the specified options.</fsummary> <type> <v>Socket = sslsocket()</v> - <v>OptionNames = [property()]</v> + <v>OptionNames = [atom()]</v> </type> <desc> <p>Get the value of the specified socket options, if no @@ -583,7 +581,7 @@ fun(OtpCert :: #'OTPCertificate'{}, Event :: {bad_cert, Reason :: atom()} | <fsummary>Write data to a socket.</fsummary> <type> <v>Socket = sslsocket()</v> - <v>Data = iolist() | binary()</v> + <v>Data = iodata()</v> </type> <desc> <p>Writes <c>Data</c> to <c>Socket</c>. </p> diff --git a/lib/ssl/src/ssl.erl b/lib/ssl/src/ssl.erl index 7b1fda4cf9..380c59b058 100644 --- a/lib/ssl/src/ssl.erl +++ b/lib/ssl/src/ssl.erl @@ -50,8 +50,7 @@ cb %% Callback info }). -type option() :: socketoption() | ssloption() | transportoption(). --type socketoption() :: [{property(), term()}]. %% See gen_tcp and inet --type property() :: atom(). +-type socketoption() :: term(). %% See gen_tcp and inet, import spec later when there is one to import -type ssloption() :: {verify, verify_type()} | {verify_fun, {fun(), InitialUserState::term()}} | {fail_if_no_peer_cert, boolean()} | {depth, integer()} | @@ -264,7 +263,7 @@ close(Socket = #sslsocket{}) -> ssl_broker:close(Socket). %%-------------------------------------------------------------------- --spec send(#sslsocket{}, iolist()) -> ok | {error, reason()}. +-spec send(#sslsocket{}, iodata()) -> ok | {error, reason()}. %% %% Description: Sends data over the ssl connection %%-------------------------------------------------------------------- @@ -403,9 +402,9 @@ cipher_suites(openssl) -> [ssl_cipher:openssl_suite_name(S) || S <- ssl_cipher:suites(Version)]. %%-------------------------------------------------------------------- --spec getopts(#sslsocket{}, [atom()]) -> {ok, [{atom(), term()}]}| {error, reason()}. +-spec getopts(#sslsocket{}, [atom()]) -> {ok, [{atom(), term()}]} | {error, reason()}. %% -%% Description: +%% Description: Gets options %%-------------------------------------------------------------------- getopts(#sslsocket{fd = new_ssl, pid = Pid}, OptTags) when is_pid(Pid) -> ssl_connection:get_opts(Pid, OptTags); @@ -416,9 +415,9 @@ getopts(#sslsocket{} = Socket, Options) -> ssl_broker:getopts(Socket, Options). %%-------------------------------------------------------------------- --spec setopts(#sslsocket{}, [{atom(), term()}]) -> ok | {error, reason()}. +-spec setopts(#sslsocket{}, [proplist:property()]) -> ok | {error, reason()}. %% -%% Description: +%% Description: Sets options %%-------------------------------------------------------------------- setopts(#sslsocket{fd = new_ssl, pid = Pid}, Opts0) when is_pid(Pid) -> Opts = proplists:expand([{binary, [{mode, binary}]}, diff --git a/lib/ssl/src/ssl_connection.erl b/lib/ssl/src/ssl_connection.erl index 574e1e9468..0a86e9bd29 100644 --- a/lib/ssl/src/ssl_connection.erl +++ b/lib/ssl/src/ssl_connection.erl @@ -107,12 +107,14 @@ %%==================================================================== %%-------------------------------------------------------------------- --spec send(pid(), iolist()) -> ok | {error, reason()}. +-spec send(pid(), iodata()) -> ok | {error, reason()}. %% %% Description: Sends data over the ssl connection %%-------------------------------------------------------------------- send(Pid, Data) -> sync_send_all_state_event(Pid, {application_data, + %% iolist_to_binary should really + %% be called iodata_to_binary() erlang:iolist_to_binary(Data)}, infinity). %%-------------------------------------------------------------------- diff --git a/lib/stdlib/doc/src/unicode.xml b/lib/stdlib/doc/src/unicode.xml index e3a25a407b..cb1cfa8ed0 100644 --- a/lib/stdlib/doc/src/unicode.xml +++ b/lib/stdlib/doc/src/unicode.xml @@ -164,10 +164,16 @@ latin1_charlist() = [latin1_char() | latin1_binary() | latin1_charlist()] <item>Integers out of range - If <c>InEncoding</c> is <c>latin1</c>, an error occurs whenever an integer greater than 255 is found in the lists. If <c>InEncoding</c> is - of a Unicode type, error occurs whenever an integer greater than - <c>16#10FFFF</c> (the maximum unicode character) or in the - range <c>16#D800</c> to <c>16#DFFF</c> (invalid unicode - range) is found.</item> + of a Unicode type, an error occurs whenever an integer + <list type="bulleted"> + <item>greater than <c>16#10FFFF</c> + (the maximum unicode character),</item> + <item>in the range <c>16#D800</c> to <c>16#DFFF</c> + (invalid unicode range)</item> + <item>or equal to 16#FFFE or 16#FFFF (non characters)</item> + </list> + is found. + </item> <item>UTF encoding incorrect - If <c>InEncoding</c> is one of the UTF types, the bytes in any binaries have to be valid diff --git a/lib/tools/emacs/erlang.el b/lib/tools/emacs/erlang.el index e1c0d31371..6728bef2a4 100644 --- a/lib/tools/emacs/erlang.el +++ b/lib/tools/emacs/erlang.el @@ -386,7 +386,8 @@ then no prototype is inserted. The test is performed by the function `erlang-test-criteria-list'.") (defvar erlang-electric-arrow-criteria - '(erlang-next-lines-empty-p + '(erlang-stop-when-in-type-spec + erlang-next-lines-empty-p erlang-at-end-of-function-p) "*List of functions controlling the arrow aspect of `erlang-electric-gt'. The functions in this list are called, in order, whenever a `>' @@ -4045,6 +4046,16 @@ This function is designed to be a member of a criteria list." nil))) +(defun erlang-stop-when-in-type-spec () + "Return `stop' when in a type spec line. + +This function is designed to be a member of a criteria list." + (save-excursion + (beginning-of-line) + (when (save-match-data (looking-at "-\\(spec\\|type\\)")) + 'stop))) + + (defun erlang-next-lines-empty-p () "Return non-nil if next lines are empty. |