aboutsummaryrefslogtreecommitdiffstats
path: root/lib/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'lib/kernel')
-rw-r--r--lib/kernel/doc/src/notes.xml16
-rw-r--r--lib/kernel/src/code_server.erl25
-rw-r--r--lib/kernel/src/erts_debug.erl15
-rw-r--r--lib/kernel/src/file_io_server.erl122
-rw-r--r--lib/kernel/src/inet.erl14
-rw-r--r--lib/kernel/test/file_SUITE.erl64
-rw-r--r--lib/kernel/test/inet_sockopt_SUITE.erl82
7 files changed, 276 insertions, 62 deletions
diff --git a/lib/kernel/doc/src/notes.xml b/lib/kernel/doc/src/notes.xml
index 1e909cb6f2..1049e72ffe 100644
--- a/lib/kernel/doc/src/notes.xml
+++ b/lib/kernel/doc/src/notes.xml
@@ -185,6 +185,22 @@
</section>
+<section><title>Kernel 3.2.0.1</title>
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>The 'raw' socket option could not be used multiple times
+ in one call to any e.g gen_tcp function because only one
+ of the occurrences were used. This bug has been fixed,
+ and also a small bug concerning propagating error codes
+ from within inet:setopts/2.</p>
+ <p>Own Id: OTP-11482 Aux Id: seq12872 </p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+
<section><title>Kernel 3.2</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/kernel/src/code_server.erl b/lib/kernel/src/code_server.erl
index e461c95d19..68dd21b1d7 100644
--- a/lib/kernel/src/code_server.erl
+++ b/lib/kernel/src/code_server.erl
@@ -1428,16 +1428,18 @@ absname_vr([[X, $:]|Name], _, _AbsBase) ->
do_purge(Mod0) ->
Mod = to_atom(Mod0),
case erlang:check_old_code(Mod) of
- false ->
- false;
- true ->
- Res = check_proc_code(erlang:processes(), Mod, true),
- try
- erlang:purge_module(Mod)
- catch
- _:_ -> ignore
- end,
- Res
+ false ->
+ false;
+ true ->
+ true = erlang:copy_literals(Mod, true),
+ Res = check_proc_code(erlang:processes(), Mod, true),
+ true = erlang:copy_literals(Mod, false),
+ try
+ erlang:purge_module(Mod)
+ catch
+ _:_ -> ignore
+ end,
+ Res
end.
%% do_soft_purge(Module)
@@ -1451,10 +1453,13 @@ do_soft_purge(Mod0) ->
false ->
true;
true ->
+ true = erlang:copy_literals(Mod, true),
case check_proc_code(erlang:processes(), Mod, false) of
false ->
+ true = erlang:copy_literals(Mod, false),
false;
true ->
+ true = erlang:copy_literals(Mod, false),
try
erlang:purge_module(Mod)
catch
diff --git a/lib/kernel/src/erts_debug.erl b/lib/kernel/src/erts_debug.erl
index 39308c0043..87f001fdf4 100644
--- a/lib/kernel/src/erts_debug.erl
+++ b/lib/kernel/src/erts_debug.erl
@@ -34,7 +34,8 @@
-export([breakpoint/2, disassemble/1, display/1, dist_ext_to_term/2,
dump_monitors/1, dump_links/1, flat_size/1,
get_internal_state/1, instructions/0, lock_counters/1,
- map_info/1, same/2, set_internal_state/2]).
+ map_info/1, same/2, set_internal_state/2,
+ size_shared/1, copy_shared/1]).
-spec breakpoint(MFA, Flag) -> non_neg_integer() when
MFA :: {Module :: module(),
@@ -86,6 +87,18 @@ dump_links(_) ->
flat_size(_) ->
erlang:nif_error(undef).
+-spec size_shared(Term) -> non_neg_integer() when
+ Term :: term().
+
+size_shared(_) ->
+ erlang:nif_error(undef).
+
+-spec copy_shared(Term) -> term() when
+ Term :: term().
+
+copy_shared(_) ->
+ erlang:nif_error(undef).
+
-spec get_internal_state(W) -> term() when
W :: reds_left | node_and_dist_references | monitoring_nodes
| next_pid | 'DbTable_words' | check_io_debug
diff --git a/lib/kernel/src/file_io_server.erl b/lib/kernel/src/file_io_server.erl
index bf8b9e2747..deb7b315b1 100644
--- a/lib/kernel/src/file_io_server.erl
+++ b/lib/kernel/src/file_io_server.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2000-2015. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -206,8 +206,8 @@ io_reply(From, ReplyAs, Reply) ->
file_request({advise,Offset,Length,Advise},
#state{handle=Handle}=State) ->
case ?PRIM_FILE:advise(Handle, Offset, Length, Advise) of
- {error,_}=Reply ->
- {stop,normal,Reply,State};
+ {error,Reason}=Reply ->
+ {stop,Reason,Reply,State};
Reply ->
{reply,Reply,State}
end;
@@ -215,62 +215,91 @@ file_request({allocate, Offset, Length},
#state{handle = Handle} = State) ->
Reply = ?PRIM_FILE:allocate(Handle, Offset, Length),
{reply, Reply, State};
+file_request({pread,At,Sz}, State)
+ when At =:= cur;
+ At =:= {cur,0} ->
+ case get_chars(Sz, latin1, State) of
+ {reply,Reply,NewState}
+ when is_list(Reply);
+ is_binary(Reply) ->
+ {reply,{ok,Reply},NewState};
+ Other ->
+ Other
+ end;
file_request({pread,At,Sz},
- #state{handle=Handle,buf=Buf,read_mode=ReadMode}=State) ->
+ #state{handle=Handle,buf=Buf}=State) ->
case position(Handle, At, Buf) of
- {ok,_Offs} ->
- case ?PRIM_FILE:read(Handle, Sz) of
- {ok,Bin} when ReadMode =:= list ->
- std_reply({ok,binary_to_list(Bin)}, State);
- Reply ->
- std_reply(Reply, State)
- end;
- Reply ->
- std_reply(Reply, State)
+ {error,_} = Reply ->
+ {error,Reply,State};
+ _ ->
+ case get_chars(Sz, latin1, State#state{buf= <<>>}) of
+ {reply,Reply,NewState}
+ when is_list(Reply);
+ is_binary(Reply) ->
+ {reply,{ok,Reply},NewState};
+ Other ->
+ Other
+ end
end;
+file_request({pwrite,At,Data},
+ #state{buf= <<>>}=State)
+ when At =:= cur;
+ At =:= {cur,0} ->
+ put_chars(Data, latin1, State);
file_request({pwrite,At,Data},
#state{handle=Handle,buf=Buf}=State) ->
case position(Handle, At, Buf) of
- {ok,_Offs} ->
- std_reply(?PRIM_FILE:write(Handle, Data), State);
- Reply ->
- std_reply(Reply, State)
+ {error,_} = Reply ->
+ {error,Reply,State};
+ _ ->
+ put_chars(Data, latin1, State)
end;
file_request(datasync,
#state{handle=Handle}=State) ->
case ?PRIM_FILE:datasync(Handle) of
- {error,_}=Reply ->
- {stop,normal,Reply,State};
+ {error,Reason}=Reply ->
+ {stop,Reason,Reply,State};
Reply ->
{reply,Reply,State}
end;
file_request(sync,
#state{handle=Handle}=State) ->
case ?PRIM_FILE:sync(Handle) of
- {error,_}=Reply ->
- {stop,normal,Reply,State};
+ {error,Reason}=Reply ->
+ {stop,Reason,Reply,State};
Reply ->
{reply,Reply,State}
end;
file_request(close,
#state{handle=Handle}=State) ->
- {stop,normal,?PRIM_FILE:close(Handle),State#state{buf= <<>>}};
+ case ?PRIM_FILE:close(Handle) of
+ {error,Reason}=Reply ->
+ {stop,Reason,Reply,State#state{buf= <<>>}};
+ Reply ->
+ {stop,normal,Reply,State#state{buf= <<>>}}
+ end;
file_request({position,At},
#state{handle=Handle,buf=Buf}=State) ->
- std_reply(position(Handle, At, Buf), State);
+ case position(Handle, At, Buf) of
+ {error,_} = Reply ->
+ {error,Reply,State};
+ Reply ->
+ std_reply(Reply, State)
+ end;
file_request(truncate,
#state{handle=Handle}=State) ->
case ?PRIM_FILE:truncate(Handle) of
- {error,_Reason}=Reply ->
- {stop,normal,Reply,State#state{buf= <<>>}};
+ {error,Reason}=Reply ->
+ {stop,Reason,Reply,State#state{buf= <<>>}};
Reply ->
- {reply,Reply,State}
+ std_reply(Reply, State)
end;
file_request(Unknown,
#state{}=State) ->
Reason = {request, Unknown},
{error,{error,Reason},State}.
+%% Standard reply and clear buffer
std_reply({error,_}=Reply, State) ->
{error,Reply,State#state{buf= <<>>}};
std_reply(Reply, State) ->
@@ -286,8 +315,8 @@ io_request({put_chars, Enc, Chars},
io_request({put_chars, Enc, Chars},
#state{handle=Handle,buf=Buf}=State) ->
case position(Handle, cur, Buf) of
- {error,_}=Reply ->
- {stop,normal,Reply,State#state{buf= <<>>}};
+ {error,Reason}=Reply ->
+ {stop,Reason,Reply,State};
_ ->
put_chars(Chars, Enc, State#state{buf= <<>>})
end;
@@ -368,23 +397,27 @@ io_request_loop([Request|Tail],
%% I/O request put_chars
%%
put_chars(Chars, latin1, #state{handle=Handle, unic=latin1}=State) ->
+ NewState = State#state{buf = <<>>},
case ?PRIM_FILE:write(Handle, Chars) of
- {error,_}=Reply ->
- {stop,normal,Reply,State};
+ {error,Reason}=Reply ->
+ {stop,Reason,Reply,NewState};
Reply ->
- {reply,Reply,State}
+ {reply,Reply,NewState}
end;
put_chars(Chars, InEncoding, #state{handle=Handle, unic=OutEncoding}=State) ->
+ NewState = State#state{buf = <<>>},
case unicode:characters_to_binary(Chars,InEncoding,OutEncoding) of
Bin when is_binary(Bin) ->
case ?PRIM_FILE:write(Handle, Bin) of
- {error,_}=Reply ->
- {stop,normal,Reply,State};
+ {error,Reason}=Reply ->
+ {stop,Reason,Reply,NewState};
Reply ->
- {reply,Reply,State}
+ {reply,Reply,NewState}
end;
{error,_,_} ->
- {stop,normal,{error,{no_translation, InEncoding, OutEncoding}},State}
+ {stop,no_translation,
+ {error,{no_translation, InEncoding, OutEncoding}},
+ NewState}
end.
get_line(S, {<<>>, Cont}, OutEnc,
@@ -884,11 +917,14 @@ cbv({utf32,little},_) ->
%% Compensates ?PRIM_FILE:position/2 for the number of bytes
%% we have buffered
-
-position(Handle, cur, Buf) ->
- position(Handle, {cur, 0}, Buf);
-position(Handle, {cur, Offs}, Buf) when is_binary(Buf) ->
- ?PRIM_FILE:position(Handle, {cur, Offs-byte_size(Buf)});
-position(Handle, At, _Buf) ->
- ?PRIM_FILE:position(Handle, At).
-
+position(Handle, At, Buf) ->
+ ?PRIM_FILE:position(
+ Handle,
+ case At of
+ cur ->
+ {cur, -byte_size(Buf)};
+ {cur, Offs} ->
+ {cur, Offs-byte_size(Buf)};
+ _ ->
+ At
+ end).
diff --git a/lib/kernel/src/inet.erl b/lib/kernel/src/inet.erl
index 855c6377a3..b573112445 100644
--- a/lib/kernel/src/inet.erl
+++ b/lib/kernel/src/inet.erl
@@ -692,6 +692,7 @@ connect_options(Opts, Family) ->
case con_opt(Opts, BaseOpts, connect_options()) of
{ok, R} ->
{ok, R#connect_opts {
+ opts = lists:reverse(R#connect_opts.opts),
ifaddr = translate_ip(R#connect_opts.ifaddr, Family)
}};
Error -> Error
@@ -762,6 +763,7 @@ listen_options(Opts, Family) ->
case list_opt(Opts, BaseOpts, listen_options()) of
{ok, R} ->
{ok, R#listen_opts {
+ opts = lists:reverse(R#listen_opts.opts),
ifaddr = translate_ip(R#listen_opts.ifaddr, Family)
}};
Error -> Error
@@ -820,6 +822,7 @@ udp_options(Opts, Family) ->
case udp_opt(Opts, #udp_opts { }, udp_options()) of
{ok, R} ->
{ok, R#udp_opts {
+ opts = lists:reverse(R#udp_opts.opts),
ifaddr = translate_ip(R#udp_opts.ifaddr, Family)
}};
Error -> Error
@@ -893,9 +896,12 @@ sctp_options() ->
sctp_options(Opts, Mod) ->
case sctp_opt(Opts, Mod, #sctp_opts{}, sctp_options()) of
{ok,#sctp_opts{ifaddr=undefined}=SO} ->
- {ok,SO#sctp_opts{ifaddr=Mod:translate_ip(?SCTP_DEF_IFADDR)}};
- {ok,_}=OK ->
- OK;
+ {ok,
+ SO#sctp_opts{
+ opts=lists:reverse(SO#sctp_opts.opts),
+ ifaddr=Mod:translate_ip(?SCTP_DEF_IFADDR)}};
+ {ok,SO} ->
+ {ok,SO#sctp_opts{opts=lists:reverse(SO#sctp_opts.opts)}};
Error -> Error
end.
@@ -967,6 +973,8 @@ add_opt(Name, Val, Opts, As) ->
case lists:member(Name, As) of
true ->
case prim_inet:is_sockopt_val(Name, Val) of
+ true when Name =:= raw ->
+ {ok, [{Name,Val} | Opts]};
true ->
Opts1 = lists:keydelete(Name, 1, Opts),
{ok, [{Name,Val} | Opts1]};
diff --git a/lib/kernel/test/file_SUITE.erl b/lib/kernel/test/file_SUITE.erl
index 5263130574..8f5027c91b 100644
--- a/lib/kernel/test/file_SUITE.erl
+++ b/lib/kernel/test/file_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2015. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -48,7 +48,7 @@
-export([cur_dir_0/1, cur_dir_1/1, make_del_dir/1,
list_dir/1,list_dir_error/1,
untranslatable_names/1, untranslatable_names_error/1,
- pos1/1, pos2/1]).
+ pos1/1, pos2/1, pos3/1]).
-export([close/1, consult1/1, path_consult/1, delete/1]).
-export([ eval1/1, path_eval/1, script1/1, path_script/1,
open1/1,
@@ -80,6 +80,7 @@
-export([interleaved_read_write/1]).
+-export([unicode/1]).
-export([altname/1]).
-export([large_file/1, large_write/1]).
@@ -114,7 +115,7 @@
suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
- [altname, read_write_file, {group, dirs},
+ [unicode, altname, read_write_file, {group, dirs},
{group, files}, delete, rename, names, {group, errors},
{group, compression}, {group, links}, copy,
delayed_write, read_ahead, segment_read, segment_write,
@@ -136,7 +137,7 @@ groups() ->
[open1, old_modes, new_modes, path_open, close, access,
read_write, pread_write, append, open_errors,
exclusive]},
- {pos, [], [pos1, pos2]},
+ {pos, [], [pos1, pos2, pos3]},
{file_info, [],
[file_info_basic_file, file_info_basic_directory,
file_info_bad, file_info_times, file_write_file_info]},
@@ -1357,6 +1358,27 @@ pos2(Config) when is_list(Config) ->
?line test_server:timetrap_cancel(Dog),
ok.
+pos3(suite) -> [];
+pos3(doc) -> ["When it does not use raw mode, file:position had a bug."];
+pos3(Config) when is_list(Config) ->
+ ?line Dog = test_server:timetrap(test_server:seconds(5)),
+ ?line RootDir = ?config(data_dir, Config),
+ ?line Name = filename:join(RootDir, "realmen.html.gz"),
+
+ ?line {ok, Fd} = ?FILE_MODULE:open(Name, [read, binary]),
+ ?line {ok, _} = ?FILE_MODULE:read(Fd, 5),
+ ?line {error, einval} = ?FILE_MODULE:position(Fd, {bof, -1}),
+
+ %% Here ok had returned =(
+ ?line {error, einval} = ?FILE_MODULE:position(Fd, {cur, -10}),
+ %% That test is actually questionable since file:position/2
+ %% is documented to leave the file position undefined after
+ %% it has returned an error. But on Posix systems the position
+ %% is guaranteed to be unchanged after an error return. On e.g
+ %% Windows there is nothing stated about this in the documentation.
+
+ ?line test_server:timetrap_cancel(Dog),
+ ok.
file_info_basic_file(suite) -> [];
file_info_basic_file(doc) -> [];
@@ -2745,6 +2767,40 @@ compress_async_crash_loop(N, Path, ExpectedData) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+unicode(Config) when is_list(Config) ->
+ Dir = ?config(priv_dir, Config),
+ Name = filename:join(Dir, "data-utf8.txt"),
+ Txt = lists:seq(128, 255),
+ D = unicode:characters_to_binary(Txt, latin1, latin1),
+ {ok,Fd1} =
+ ?FILE_MODULE:open(Name, [write,read,binary,{encoding,unicode}]),
+ ok = ?FILE_MODULE:truncate(Fd1),
+ ok = ?FILE_MODULE:write(Fd1, Txt),
+ {ok,0} = ?FILE_MODULE:position(Fd1, bof),
+ {ok,D} = ?FILE_MODULE:read(Fd1, 129),
+ {ok,0} = ?FILE_MODULE:position(Fd1, bof),
+ {ok,D1} = ?FILE_MODULE:read(Fd1, 64),
+ {ok,Pos} = ?FILE_MODULE:position(Fd1, cur),
+ {ok,D2} = ?FILE_MODULE:pread(Fd1, {cur,0}, 65),
+ D = <<D1/binary, D2/binary>>,
+ {ok,D1} = ?FILE_MODULE:pread(Fd1, bof, 64),
+ {ok,Pos} = ?FILE_MODULE:position(Fd1, Pos),
+ {ok,D2} = ?FILE_MODULE:read(Fd1, 64),
+ ok = ?FILE_MODULE:close(Fd1),
+ %%
+ RawD = unicode:characters_to_binary(Txt, latin1, unicode),
+ {ok,RawD} = ?FILE_MODULE:read_file(Name),
+ %%
+ {ok,Fd2} = ?FILE_MODULE:open(Name, [read,{encoding,unicode}]),
+ {ok,Txt} = ?FILE_MODULE:read(Fd2, 129),
+ {Txt1,Txt2} = lists:split(64, Txt),
+ {ok,Txt2} = ?FILE_MODULE:pread(Fd2, Pos, 65),
+ {ok,0} = ?FILE_MODULE:position(Fd2, bof),
+ {ok,Txt1} = ?FILE_MODULE:read(Fd2, 64),
+ ok = ?FILE_MODULE:close(Fd2).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
altname(doc) ->
"Test the file:altname/1 function";
altname(suite) ->
diff --git a/lib/kernel/test/inet_sockopt_SUITE.erl b/lib/kernel/test/inet_sockopt_SUITE.erl
index 1262f36fae..cb522c8abe 100644
--- a/lib/kernel/test/inet_sockopt_SUITE.erl
+++ b/lib/kernel/test/inet_sockopt_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2015. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -52,6 +52,7 @@
-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
init_per_group/2,end_per_group/2,
simple/1, loop_all/1, simple_raw/1, simple_raw_getbin/1,
+ multiple_raw/1, multiple_raw_getbin/1,
doc_examples_raw/1,doc_examples_raw_getbin/1,
large_raw/1,large_raw_getbin/1,combined/1,combined_getbin/1,
ipv6_v6only_udp/1, ipv6_v6only_tcp/1, ipv6_v6only_sctp/1,
@@ -65,6 +66,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
[simple, loop_all, simple_raw, simple_raw_getbin,
+ multiple_raw, multiple_raw_getbin,
doc_examples_raw, doc_examples_raw_getbin, large_raw,
large_raw_getbin, combined, combined_getbin,
ipv6_v6only_udp, ipv6_v6only_tcp, ipv6_v6only_sctp,
@@ -185,6 +187,84 @@ nintbin2int(<<Int:16/native>>) -> Int;
nintbin2int(<<Int:8/native>>) -> Int;
nintbin2int(<<>>) -> 0.
+
+
+multiple_raw(suite) -> [];
+multiple_raw(doc) -> "Test setopt/getopt of multiple raw options.";
+multiple_raw(Config) when is_list(Config) ->
+ do_multiple_raw(Config,false).
+multiple_raw_getbin(suite) -> [];
+multiple_raw_getbin(doc) -> "Test setopt/getopt of multiple raw options, "
+ "with binaries in getopt.";
+multiple_raw_getbin(Config) when is_list(Config) ->
+ do_multiple_raw(Config,true).
+
+do_multiple_raw(Config, Binary) ->
+ Port = start_helper(Config),
+ SolSocket = ask_helper(Port, ?C_GET_SOL_SOCKET),
+ SoKeepalive = ask_helper(Port, ?C_GET_SO_KEEPALIVE),
+ SoKeepaliveTrue = {raw,SolSocket,SoKeepalive,<<1:32/native>>},
+ SoKeepaliveFalse = {raw,SolSocket,SoKeepalive,<<0:32/native>>},
+ SoReuseaddr = ask_helper(Port, ?C_GET_SO_REUSEADDR),
+ SoReuseaddrTrue = {raw,SolSocket,SoReuseaddr,<<1:32/native>>},
+ SoReuseaddrFalse = {raw,SolSocket,SoReuseaddr,<<0:32/native>>},
+ {S1,S2} =
+ create_socketpair(
+ [SoReuseaddrFalse,SoKeepaliveTrue],
+ [SoKeepaliveFalse,SoReuseaddrTrue]),
+ {ok,[{reuseaddr,false},{keepalive,true}]} =
+ inet:getopts(S1, [reuseaddr,keepalive]),
+ {ok,
+ [{raw,SolSocket,SoReuseaddr,S1R1},
+ {raw,SolSocket,SoKeepalive,S1K1}]} =
+ inet:getopts(
+ S1,
+ [{raw,SolSocket,SoReuseaddr,binarify(4, Binary)},
+ {raw,SolSocket,SoKeepalive,binarify(4, Binary)}]),
+ true = nintbin2int(S1R1) =:= 0,
+ true = nintbin2int(S1K1) =/= 0,
+ {ok,[{keepalive,false},{reuseaddr,true}]} =
+ inet:getopts(S2, [keepalive,reuseaddr]),
+ {ok,
+ [{raw,SolSocket,SoKeepalive,S2K1},
+ {raw,SolSocket,SoReuseaddr,S2R1}]} =
+ inet:getopts(
+ S2,
+ [{raw,SolSocket,SoKeepalive,binarify(4, Binary)},
+ {raw,SolSocket,SoReuseaddr,binarify(4, Binary)}]),
+ true = nintbin2int(S2K1) =:= 0,
+ true = nintbin2int(S2R1) =/= 0,
+ %%
+ ok = inet:setopts(
+ S1, [SoReuseaddrTrue,SoKeepaliveFalse]),
+ ok = inet:setopts(
+ S2, [SoKeepaliveTrue,SoReuseaddrFalse]),
+ {ok,
+ [{raw,SolSocket,SoReuseaddr,S1R2},
+ {raw,SolSocket,SoKeepalive,S1K2}]} =
+ inet:getopts(
+ S1,
+ [{raw,SolSocket,SoReuseaddr,binarify(4, Binary)},
+ {raw,SolSocket,SoKeepalive,binarify(4, Binary)}]),
+ true = nintbin2int(S1R2) =/= 0,
+ true = nintbin2int(S1K2) =:= 0,
+ {ok,
+ [{raw,SolSocket,SoKeepalive,S2K2},
+ {raw,SolSocket,SoReuseaddr,S2R2}]} =
+ inet:getopts(
+ S2,
+ [{raw,SolSocket,SoKeepalive,binarify(4, Binary)},
+ {raw,SolSocket,SoReuseaddr,binarify(4, Binary)}]),
+ true = nintbin2int(S2K2) =/= 0,
+ true = nintbin2int(S2R2) =:= 0,
+ %%
+ gen_tcp:close(S1),
+ gen_tcp:close(S2),
+ stop_helper(Port),
+ ok.
+
+
+
doc_examples_raw(suite) -> [];
doc_examples_raw(doc) -> "Test that the example code from the documentation "
"works";