diff options
Diffstat (limited to 'lib/kernel')
-rw-r--r-- | lib/kernel/doc/src/code.xml | 2 | ||||
-rw-r--r-- | lib/kernel/doc/src/erl_ddll.xml | 38 | ||||
-rw-r--r-- | lib/kernel/src/code.erl | 18 | ||||
-rw-r--r-- | lib/kernel/src/gen_sctp.erl | 8 | ||||
-rw-r--r-- | lib/kernel/src/inet6_sctp.erl | 23 | ||||
-rw-r--r-- | lib/kernel/src/inet_sctp.erl | 21 | ||||
-rw-r--r-- | lib/kernel/src/net_kernel.erl | 4 | ||||
-rw-r--r-- | lib/kernel/test/code_SUITE.erl | 32 | ||||
-rw-r--r-- | lib/kernel/test/erl_distribution_SUITE.erl | 2 | ||||
-rw-r--r-- | lib/kernel/test/gen_sctp_SUITE.erl | 189 | ||||
-rw-r--r-- | lib/kernel/vsn.mk | 19 |
11 files changed, 294 insertions, 62 deletions
diff --git a/lib/kernel/doc/src/code.xml b/lib/kernel/doc/src/code.xml index 19e1d3221c..b8db509fa8 100644 --- a/lib/kernel/doc/src/code.xml +++ b/lib/kernel/doc/src/code.xml @@ -54,7 +54,7 @@ for and tries to load the module.</p> </item> </list> - <p>To prevent accidentaly reloading modules affecting the Erlang + <p>To prevent accidentally reloading modules affecting the Erlang runtime system itself, the <c>kernel</c>, <c>stdlib</c> and <c>compiler</c> directories are considered <em>sticky</em>. This means that the system issues a warning and rejects the request if diff --git a/lib/kernel/doc/src/erl_ddll.xml b/lib/kernel/doc/src/erl_ddll.xml index 4e65bf46f8..9a62b45d63 100644 --- a/lib/kernel/doc/src/erl_ddll.xml +++ b/lib/kernel/doc/src/erl_ddll.xml @@ -177,7 +177,7 @@ <name>demonitor(MonitorRef) -> ok</name> <fsummary>Remove a monitor for a driver</fsummary> <type> - <v>MonitorRef = ref()</v> + <v>MonitorRef = reference()</v> </type> <desc> <p>Removes a driver monitor in much the same way as @@ -185,7 +185,7 @@ monitors. See <seealso marker="#monitor/2">monitor/2</seealso>, <seealso marker="#try_load/3">try_load/3</seealso> and <seealso marker="#try_unload/2">try_unload/2</seealso> for details about how to create driver monitors.</p> <p>The function throws a <c>badarg</c> exception if the - parameter is not a ref(). </p> + parameter is not a reference(). </p> </desc> </func> <func> @@ -400,7 +400,7 @@ <v>Item = {Name, When}</v> <v>Name = atom() | string()</v> <v>When = loaded | unloaded | unloaded_only</v> - <v>MonitorRef = ref()</v> + <v>MonitorRef = reference()</v> </type> <desc> <p>This function creates a driver monitor and works in many @@ -449,7 +449,7 @@ eventually lead to one of the following messages being sent:</p> <taglist> - <tag><em>{'UP', ref(), driver, Name, loaded}</em></tag> + <tag><em>{'UP', reference(), driver, Name, loaded}</em></tag> <item> <p>This message is sent, either immediately if the driver is already loaded and no reloading is @@ -459,7 +459,7 @@ expected to know if reloading is demanded prior to creating a monitor for loading.</p> </item> - <tag><em>{'UP', ref(), driver, Name, permanent}</em></tag> + <tag><em>{'UP', reference(), driver, Name, permanent}</em></tag> <item> <p>This message will be sent if reloading was expected, but the (old) driver made itself @@ -467,7 +467,7 @@ sent if the driver was permanent or statically linked in when trying to create the monitor.</p> </item> - <tag><em>{'DOWN', ref(), driver, Name, load_cancelled}</em></tag> + <tag><em>{'DOWN', reference(), driver, Name, load_cancelled}</em></tag> <item> <p>This message will arrive if reloading was underway, but the <seealso marker="#users">user</seealso> having requested @@ -476,7 +476,7 @@ (or <c>unload/1</c>/<c>unload_driver/1</c>) again before it was reloaded.</p> </item> - <tag><em>{'DOWN', ref(), driver, Name, {load_failure, Failure}}</em></tag> + <tag><em>{'DOWN', reference(), driver, Name, {load_failure, Failure}}</em></tag> <item> <p>This message will arrive if reloading was underway but the loading for some reason @@ -500,7 +500,7 @@ <p>A driver monitor for unload will eventually result in one of the following messages being sent:</p> <taglist> - <tag><em>{'DOWN', ref(), driver, Name, unloaded}</em></tag> + <tag><em>{'DOWN', reference(), driver, Name, unloaded}</em></tag> <item> <p>The driver instance monitored is now unloaded. As the unload might have been due to a @@ -508,7 +508,7 @@ again have been loaded when this message arrives.</p> </item> - <tag><em>{'UP', ref(), driver, Name, unload_cancelled}</em></tag> + <tag><em>{'UP', reference(), driver, Name, unload_cancelled}</em></tag> <item> <p>This message will be sent if unloading was expected, but while the driver was waiting for @@ -525,7 +525,7 @@ similar to an <c>unloaded</c> monitor, but does never result in this message.</p> </item> - <tag><em>{'UP', ref(), driver, Name, permanent}</em></tag> + <tag><em>{'UP', reference(), driver, Name, permanent}</em></tag> <item> <p>This message will be sent if unloading was expected, but the driver made itself @@ -539,7 +539,7 @@ <item> <p>A monitor created as <c>unloaded_only</c> behaves exactly as one created as <c>unloaded</c> with the - exception that the <c>{'UP', ref(), driver, Name, unload_cancelled}</c> message will never be + exception that the <c>{'UP', reference(), driver, Name, unload_cancelled}</c> message will never be sent, but the monitor instead persists until the driver <em>really</em> gets unloaded.</p> </item> @@ -626,7 +626,7 @@ <v>ReloadOption = pending_driver | pending</v> <v>Status = loaded | already_loaded | PendingStatus </v> <v>PendingStatus = pending_driver | pending_process</v> - <v>Ref = ref()</v> + <v>Ref = reference()</v> <v>ErrorDesc = ErrorAtom | OpaqueError</v> <v>ErrorAtom = linked_in_driver | inconsistent | permanent | not_loaded_by_this_process | not_loaded | pending_reload | pending_process</v> </type> @@ -650,7 +650,7 @@ registered and a corresponding <c>try_unload</c> is expected sometime in the future.</p> </item> - <tag><em>{ok, pending_driver}</em>or <em>{ok, pending_driver, ref()}</em></tag> + <tag><em>{ok, pending_driver}</em>or <em>{ok, pending_driver, reference()}</em></tag> <item> <p>The load request is registered, but the loading is delayed due to the fact that an earlier instance of the @@ -665,7 +665,7 @@ set. In other words, this return value will always need to be handled!</p> </item> - <tag><em>{ok, pending_process}</em>or <em>{ok, pending_process, ref()}</em></tag> + <tag><em>{ok, pending_process}</em>or <em>{ok, pending_process, reference()}</em></tag> <item> <p>The load request is registered, but the loading is delayed due to the fact that an earlier instance of the @@ -683,7 +683,7 @@ about when the driver is <em>actually</em> loaded. This can be achieved by using the <c>{monitor, PendingOption}</c> option.</p> <p>When monitoring is requested, and a corresponding <c>{ok, pending_driver}</c> or <c>{ok, pending_process}</c> would be - returned, the function will instead return a tuple <c>{ok, PendingStatus, ref()}</c> and the process will, at a later + returned, the function will instead return a tuple <c>{ok, PendingStatus, reference()}</c> and the process will, at a later time when the driver actually gets loaded, get a monitor message. The monitor message one can expect is described in the <seealso marker="#monitor/2">monitor/2</seealso> @@ -760,7 +760,7 @@ <p>A <c>MonitorOption</c> tells <c>try_load/3</c> to trigger a driver monitor under certain conditions. When the monitor is triggered, the - function will return a three-tuple <c>{ok, PendingStatus, ref()}</c>, where the <c>ref()</c> is + function will return a three-tuple <c>{ok, PendingStatus, reference()}</c>, where the <c>reference()</c> is the monitor ref for the driver monitor.</p> <p>Only one <c>MonitorOption</c> can be specified and it is either the atom <c>pending</c>, which means @@ -891,7 +891,7 @@ <v>MonitorOption = pending_driver | pending</v> <v>Status = unloaded | PendingStatus </v> <v>PendingStatus = pending_driver | pending_process</v> - <v>Ref = ref()</v> + <v>Ref = reference()</v> <v>ErrorAtom = linked_in_driver | not_loaded | not_loaded_by_this_process | permanent</v> </type> <desc> @@ -943,7 +943,7 @@ ports using it and there are no more <seealso marker="#users">users</seealso> requiring it to be loaded.</p> </item> - <tag><em>{ok, pending_driver}</em>or <em>{ok, pending_driver, ref()}</em></tag> + <tag><em>{ok, pending_driver}</em>or <em>{ok, pending_driver, reference()}</em></tag> <item> <p>This return value indicates that this call removed the last <seealso marker="#users">user</seealso> from the @@ -957,7 +957,7 @@ in that case, however transient. Monitors are as always useful to detect when the driver is really unloaded.</p> </item> - <tag><em>{ok, pending_process}</em>or <em>{ok, pending_process, ref()}</em></tag> + <tag><em>{ok, pending_process}</em>or <em>{ok, pending_process, reference()}</em></tag> <item> <p>The unload request is registered, but there are still other <seealso marker="#users">users</seealso> holding diff --git a/lib/kernel/src/code.erl b/lib/kernel/src/code.erl index 42d4818f08..ec256d5806 100644 --- a/lib/kernel/src/code.erl +++ b/lib/kernel/src/code.erl @@ -304,6 +304,8 @@ do_start(Flags) -> true -> ok end, + % Quietly load the native code for all modules loaded so far. + catch load_native_code_for_all_loaded(), Ok2; Other -> Other @@ -496,3 +498,19 @@ has_ext(Ext, Extlen,File) -> to_path(X) -> filename:join(packages:split(X)). + +-spec load_native_code_for_all_loaded() -> ok. +load_native_code_for_all_loaded() -> + Architecture = erlang:system_info(hipe_architecture), + ChunkName = hipe_unified_loader:chunk_name(Architecture), + lists:foreach(fun({Module, BeamFilename}) -> + case code:is_module_native(Module) of + false -> + case beam_lib:chunks(BeamFilename, [ChunkName]) of + {ok,{_,[{_,Bin}]}} when is_binary(Bin) -> + load_native_partial(Module, Bin); + {error, beam_lib, _} -> ok + end; + true -> ok + end + end, all_loaded()). diff --git a/lib/kernel/src/gen_sctp.erl b/lib/kernel/src/gen_sctp.erl index 5a31e3976f..a1542ab507 100644 --- a/lib/kernel/src/gen_sctp.erl +++ b/lib/kernel/src/gen_sctp.erl @@ -166,18 +166,14 @@ send(S, #sctp_assoc_change{assoc_id=AssocId}, Stream, Data) when is_port(S), is_integer(Stream) -> case inet_db:lookup_socket(S) of {ok,Mod} -> - Mod:sendmsg(S, #sctp_sndrcvinfo{ - stream = Stream, - assoc_id = AssocId}, Data); + Mod:send(S, AssocId, Stream, Data); Error -> Error end; send(S, AssocId, Stream, Data) when is_port(S), is_integer(AssocId), is_integer(Stream) -> case inet_db:lookup_socket(S) of {ok,Mod} -> - Mod:sendmsg(S, #sctp_sndrcvinfo{ - stream = Stream, - assoc_id = AssocId}, Data); + Mod:send(S, AssocId, Stream, Data); Error -> Error end; send(S, AssocChange, Stream, Data) -> diff --git a/lib/kernel/src/inet6_sctp.erl b/lib/kernel/src/inet6_sctp.erl index 5c49c4fec3..5bf3fca647 100644 --- a/lib/kernel/src/inet6_sctp.erl +++ b/lib/kernel/src/inet6_sctp.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2007-2009. All Rights Reserved. +%% Copyright Ericsson AB 2007-2010. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -32,7 +32,7 @@ -define(FAMILY, inet6). -export([getserv/1,getaddr/1,getaddr/2,translate_ip/1]). --export([open/1,close/1,listen/2,connect/5,sendmsg/3,recv/2]). +-export([open/1,close/1,listen/2,connect/5,sendmsg/3,send/4,recv/2]). @@ -71,5 +71,24 @@ connect(S, Addr, Port, Opts, Timer) -> sendmsg(S, SRI, Data) -> prim_inet:sendmsg(S, SRI, Data). +send(S, AssocId, Stream, Data) -> + case prim_inet:getopts( + S, + [{sctp_default_send_param,#sctp_sndrcvinfo{assoc_id=AssocId}}]) of + {ok, + [{sctp_default_send_param, + #sctp_sndrcvinfo{ + flags=Flags, context=Context, ppid=PPID, timetolive=TTL}}]} -> + prim_inet:sendmsg( + S, + #sctp_sndrcvinfo{ + flags=Flags, context=Context, ppid=PPID, timetolive=TTL, + assoc_id=AssocId, stream=Stream}, + Data); + _ -> + prim_inet:sendmsg( + S, #sctp_sndrcvinfo{assoc_id=AssocId, stream=Stream}, Data) + end. + recv(S, Timeout) -> prim_inet:recvfrom(S, 0, Timeout). diff --git a/lib/kernel/src/inet_sctp.erl b/lib/kernel/src/inet_sctp.erl index 795bf83807..de74b573bd 100644 --- a/lib/kernel/src/inet_sctp.erl +++ b/lib/kernel/src/inet_sctp.erl @@ -31,7 +31,7 @@ -define(FAMILY, inet). -export([getserv/1,getaddr/1,getaddr/2,translate_ip/1]). --export([open/1,close/1,listen/2,connect/5,sendmsg/3,recv/2]). +-export([open/1,close/1,listen/2,connect/5,sendmsg/3,send/4,recv/2]). @@ -141,5 +141,24 @@ connect_get_assoc(S, Addr, Port, Active, Timer) -> sendmsg(S, SRI, Data) -> prim_inet:sendmsg(S, SRI, Data). +send(S, AssocId, Stream, Data) -> + case prim_inet:getopts( + S, + [{sctp_default_send_param,#sctp_sndrcvinfo{assoc_id=AssocId}}]) of + {ok, + [{sctp_default_send_param, + #sctp_sndrcvinfo{ + flags=Flags, context=Context, ppid=PPID, timetolive=TTL}}]} -> + prim_inet:sendmsg( + S, + #sctp_sndrcvinfo{ + flags=Flags, context=Context, ppid=PPID, timetolive=TTL, + assoc_id=AssocId, stream=Stream}, + Data); + _ -> + prim_inet:sendmsg( + S, #sctp_sndrcvinfo{assoc_id=AssocId, stream=Stream}, Data) + end. + recv(S, Timeout) -> prim_inet:recvfrom(S, 0, Timeout). diff --git a/lib/kernel/src/net_kernel.erl b/lib/kernel/src/net_kernel.erl index 0e5cc8c2c6..f5e2820bbe 100644 --- a/lib/kernel/src/net_kernel.erl +++ b/lib/kernel/src/net_kernel.erl @@ -500,8 +500,8 @@ handle_call({new_ticktime,T,TP}, From, #state{tick = #tick{ticker = Tckr, time = T, how = How}}}, From); -handle_call({new_ticktime,From,_}, - _, +handle_call({new_ticktime,_T,_TP}, + From, #state{tick = #tick_change{time = T}} = State) -> async_reply({reply, {ongoing_change_to, T}, State}, From); diff --git a/lib/kernel/test/code_SUITE.erl b/lib/kernel/test/code_SUITE.erl index 08b6477c9d..c9437df258 100644 --- a/lib/kernel/test/code_SUITE.erl +++ b/lib/kernel/test/code_SUITE.erl @@ -31,7 +31,7 @@ where_is_file_cached/1, where_is_file_no_cache/1, purge_stacktrace/1, mult_lib_roots/1, bad_erl_libs/1, code_archive/1, code_archive2/1, on_load/1, - on_load_embedded/1, on_load_errors/1]). + on_load_embedded/1, on_load_errors/1, native_early_modules/1]). -export([init_per_testcase/2, fin_per_testcase/2, init_per_suite/1, end_per_suite/1, @@ -53,7 +53,7 @@ all(suite) -> where_is_file_no_cache, where_is_file_cached, purge_stacktrace, mult_lib_roots, bad_erl_libs, code_archive, code_archive2, on_load, on_load_embedded, - on_load_errors]. + on_load_errors, native_early_modules]. init_per_suite(Config) -> %% The compiler will no longer create a Beam file if @@ -1333,6 +1333,34 @@ do_on_load_error(ReturnValue) -> ?line {undef,[{on_load_error,main,[]}|_]} = Exit end. +native_early_modules(suite) -> []; +native_early_modules(doc) -> ["Test that the native code of early loaded modules is loaded"]; +native_early_modules(Config) when is_list(Config) -> + case erlang:system_info(hipe_architecture) of + undefined -> + {skip,"Native code support is not enabled"}; + Architecture -> + native_early_modules_1(Architecture) + end. + +native_early_modules_1(Architecture) -> + ?line {lists, ListsBinary, _ListsFilename} = code:get_object_code(lists), + ?line ChunkName = hipe_unified_loader:chunk_name(Architecture), + ?line NativeChunk = beam_lib:chunks(ListsBinary, [ChunkName]), + ?line IsHipeCompiled = case NativeChunk of + {ok,{_,[{_,Bin}]}} when is_binary(Bin) -> true; + {error, beam_lib, _} -> false + end, + case IsHipeCompiled of + false -> + {skip,"OTP apparently not configured with --enable-native-libs"}; + true -> + ?line true = lists:all(fun code:is_module_native/1, + [ets,file,filename,gb_sets,gb_trees, + hipe_unified_loader,lists,os,packages]), + ok + end. + %%----------------------------------------------------------------- %% error_logger handler. %% (Copied from stdlib/test/proc_lib_SUITE.erl.) diff --git a/lib/kernel/test/erl_distribution_SUITE.erl b/lib/kernel/test/erl_distribution_SUITE.erl index d15f6aa0d5..21a96f804a 100644 --- a/lib/kernel/test/erl_distribution_SUITE.erl +++ b/lib/kernel/test/erl_distribution_SUITE.erl @@ -273,6 +273,7 @@ tick_change(Config) when is_list(Config) -> ?line PaDir = filename:dirname(code:which(?MODULE)), ?line [BN, CN] = get_nodenames(2, tick_change), ?line DefaultTT = net_kernel:get_net_ticktime(), + ?line unchanged = net_kernel:set_net_ticktime(DefaultTT, 60), ?line case DefaultTT of I when is_integer(I) -> ?line ok; _ -> ?line ?t:fail(DefaultTT) @@ -377,6 +378,7 @@ run_tick_change_test(B, C, PrevTT, TT, PaDir) -> end, ?line change_initiated = net_kernel:set_net_ticktime(TT,20), + ?line {ongoing_change_to,_} = net_kernel:set_net_ticktime(TT,20), ?line sleep(3), ?line change_initiated = rpc:call(B,net_kernel,set_net_ticktime,[TT,15]), ?line sleep(7), diff --git a/lib/kernel/test/gen_sctp_SUITE.erl b/lib/kernel/test/gen_sctp_SUITE.erl index fad8c7398b..eb06d4324b 100644 --- a/lib/kernel/test/gen_sctp_SUITE.erl +++ b/lib/kernel/test/gen_sctp_SUITE.erl @@ -23,12 +23,16 @@ %%-compile(export_all). --export([all/1,init_per_testcase/2,fin_per_testcase/2, - basic/1,api_open_close/1,api_listen/1,api_connect_init/1, - xfer_min/1,xfer_active/1]). +-export([all/1,init_per_testcase/2,fin_per_testcase/2]). +-export( + [basic/1, + api_open_close/1,api_listen/1,api_connect_init/1,api_opts/1, + xfer_min/1,xfer_active/1,def_sndrcvinfo/1]). all(suite) -> - [basic,api_open_close,api_listen,api_connect_init,xfer_min,xfer_active]. + [basic, + api_open_close,api_listen,api_connect_init,api_opts, + xfer_min,xfer_active,def_sndrcvinfo]. init_per_testcase(_Func, Config) -> Dog = test_server:timetrap(test_server:seconds(15)), @@ -39,6 +43,10 @@ fin_per_testcase(_Func, Config) -> +-define(LOGVAR(Var), begin io:format(??Var" = ~p~n", [Var]) end). + + + basic(doc) -> "Hello world"; basic(suite) -> @@ -214,12 +222,17 @@ xfer_active(Config) when is_list(Config) -> end, ?line ok = gen_sctp:close(Sb), ?line receive - {sctp,Sa,Loopback,Pb, - {[], - #sctp_assoc_change{state=comm_lost, - assoc_id=SaAssocId}}} -> ok - after 17 -> ok %% On Solaris this does not arrive - end, + {sctp,Sa,Loopback,Pb, + {[], + #sctp_assoc_change{state=comm_lost, + assoc_id=SaAssocId}}} -> ok + after Timeout -> + ?line test_server:fail({unexpected,flush()}) + end, + ?line receive + {sctp_error,Sa,enotconn} -> ok % Solaris + after 17 -> ok %% Only happens on Solaris + end, ?line ok = gen_sctp:close(Sa), %% ?line receive @@ -228,6 +241,148 @@ xfer_active(Config) when is_list(Config) -> end, ok. +def_sndrcvinfo(doc) -> + "Test that #sctp_sndrcvinfo{} parameters set on a socket " + "are used by gen_sctp:send/4"; +def_sndrcvinfo(suite) -> + []; +def_sndrcvinfo(Config) when is_list(Config) -> + ?line Loopback = {127,0,0,1}, + ?line Data = <<"What goes up, must come down.">>, + %% + ?line S1 = + ok(gen_sctp:open( + 0, [{sctp_default_send_param,#sctp_sndrcvinfo{ppid=17}}])), + ?LOGVAR(S1), + ?line P1 = + ok(inet:port(S1)), + ?LOGVAR(P1), + ?line #sctp_sndrcvinfo{ppid=17, context=0, timetolive=0, assoc_id=0} = + getopt(S1, sctp_default_send_param), + ?line ok = + gen_sctp:listen(S1, true), + %% + ?line S2 = + ok(gen_sctp:open()), + ?LOGVAR(S2), + ?line P2 = + ok(inet:port(S2)), + ?LOGVAR(P2), + ?line #sctp_sndrcvinfo{ppid=0, context=0, timetolive=0, assoc_id=0} = + getopt(S2, sctp_default_send_param), + %% + ?line #sctp_assoc_change{ + state=comm_up, + error=0, + assoc_id=S2AssocId} = S2AssocChange = + ok(gen_sctp:connect(S2, Loopback, P1, [])), + ?LOGVAR(S2AssocChange), + ?line case ok(gen_sctp:recv(S1)) of + {Loopback, P2,[], + #sctp_assoc_change{ + state=comm_up, + error=0, + assoc_id=S1AssocId}} -> + ?LOGVAR(S1AssocId) + end, + ?line #sctp_sndrcvinfo{ + ppid=17, context=0, timetolive=0, assoc_id=S1AssocId} = + getopt( + S1, sctp_default_send_param, #sctp_sndrcvinfo{assoc_id=S1AssocId}), + ?line #sctp_sndrcvinfo{ + ppid=0, context=0, timetolive=0, assoc_id=S2AssocId} = + getopt( + S2, sctp_default_send_param, #sctp_sndrcvinfo{assoc_id=S2AssocId}), + %% + ?line ok = + gen_sctp:send(S1, S1AssocId, 1, <<"1: ",Data/binary>>), + ?line case ok(gen_sctp:recv(S2)) of + {Loopback,P1, + [#sctp_sndrcvinfo{ + stream=1, ppid=17, context=0, assoc_id=S2AssocId}], + <<"1: ",Data/binary>>} -> ok + end, + %% + ?line ok = + setopt( + S1, sctp_default_send_param, #sctp_sndrcvinfo{ppid=18}), + ?line ok = + setopt( + S1, sctp_default_send_param, + #sctp_sndrcvinfo{ppid=19, assoc_id=S1AssocId}), + ?line #sctp_sndrcvinfo{ + ppid=18, context=0, timetolive=0, assoc_id=0} = + getopt(S1, sctp_default_send_param), + ?line #sctp_sndrcvinfo{ + ppid=19, context=0, timetolive=0, assoc_id=S1AssocId} = + getopt( + S1, sctp_default_send_param, #sctp_sndrcvinfo{assoc_id=S1AssocId}), + %% + ?line ok = + gen_sctp:send(S1, S1AssocId, 0, <<"2: ",Data/binary>>), + ?line case ok(gen_sctp:recv(S2)) of + {Loopback,P1, + [#sctp_sndrcvinfo{ + stream=0, ppid=19, context=0, assoc_id=S2AssocId}], + <<"2: ",Data/binary>>} -> ok + end, + ?line ok = + gen_sctp:send(S2, S2AssocChange, 1, <<"3: ",Data/binary>>), + ?line case ok(gen_sctp:recv(S1)) of + {Loopback,P2, + [#sctp_sndrcvinfo{ + stream=1, ppid=0, context=0, assoc_id=S1AssocId}], + <<"3: ",Data/binary>>} -> ok; + {Loopback,P2,[], + #sctp_paddr_change{ + addr={Loopback,_}, state=addr_available, + error=0, assoc_id=S1AssocId}} -> + ?line case ok(gen_sctp:recv(S1)) of + {Loopback,P2, + [#sctp_sndrcvinfo{ + stream=1, ppid=0, context=0, + assoc_id=S1AssocId}], + <<"3: ",Data/binary>>} -> ok + end + end, + ?line ok = + gen_sctp:send( + S2, + #sctp_sndrcvinfo{stream=0, ppid=20, assoc_id=S2AssocId}, + <<"4: ",Data/binary>>), + ?line case ok(gen_sctp:recv(S1)) of + {Loopback,P2, + [#sctp_sndrcvinfo{ + stream=0, ppid=20, context=0, assoc_id=S1AssocId}], + <<"4: ",Data/binary>>} -> ok + end, + %% + ?line ok = + gen_sctp:close(S1), + ?line ok = + gen_sctp:close(S2), + ?line receive + Msg -> + test_server:fail({received,Msg}) + after 17 -> ok + end, + ok. + +getopt(S, Opt) -> + {ok,[{Opt,Val}]} = inet:getopts(S, [Opt]), + Val. + +getopt(S, Opt, Param) -> + {ok,[{Opt,Val}]} = inet:getopts(S, [{Opt,Param}]), + Val. + +setopt(S, Opt, Val) -> + inet:setopts(S, [{Opt,Val}]). + +ok({ok,X}) -> + io:format("OK: ~p~n", [X]), + X. + flush() -> receive Msg -> @@ -382,3 +537,17 @@ api_connect_init(Config) when is_list(Config) -> ?line ok = gen_sctp:close(Sa), ?line ok = gen_sctp:close(Sb), ok. + +api_opts(doc) -> + "Test socket options"; +api_opts(suite) -> + []; +api_opts(Config) when is_list(Config) -> + ?line {ok,S} = gen_sctp:open(0), + ?line OSType = os:type(), + ?line case {inet:setopts(S, [{linger,{true,2}}]),OSType} of + {ok,_} -> + ok; + {{error,einval},{unix,sunos}} -> + ok + end. diff --git a/lib/kernel/vsn.mk b/lib/kernel/vsn.mk index 9a191f9aeb..651d082379 100644 --- a/lib/kernel/vsn.mk +++ b/lib/kernel/vsn.mk @@ -1,20 +1 @@ -# -# %CopyrightBegin% -# -# Copyright Ericsson AB 1997-2010. All Rights Reserved. -# -# The contents of this file are subject to the Erlang Public License, -# Version 1.1, (the "License"); you may not use this file except in -# compliance with the License. You should have received a copy of the -# Erlang Public License along with this software. If not, it can be -# retrieved online at http://www.erlang.org/. -# -# Software distributed under the License is distributed on an "AS IS" -# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -# the License for the specific language governing rights and limitations -# under the License. -# -# %CopyrightEnd% -# - KERNEL_VSN = 2.14.1 |