diff options
Diffstat (limited to 'lib/kernel')
28 files changed, 589 insertions, 157 deletions
diff --git a/lib/kernel/doc/src/disk_log.xml b/lib/kernel/doc/src/disk_log.xml index 570d3ef9bd..1be28adfb8 100644 --- a/lib/kernel/doc/src/disk_log.xml +++ b/lib/kernel/doc/src/disk_log.xml @@ -5,7 +5,7 @@ <header> <copyright> <year>1997</year> - <year>2016</year> + <year>2017</year> <holder>Ericsson AB, All Rights Reserved</holder> </copyright> <legalnotice> diff --git a/lib/kernel/doc/src/error_logger.xml b/lib/kernel/doc/src/error_logger.xml index 814e8eac46..91bf57cb91 100644 --- a/lib/kernel/doc/src/error_logger.xml +++ b/lib/kernel/doc/src/error_logger.xml @@ -4,7 +4,7 @@ <erlref> <header> <copyright> - <year>1996</year><year>2016</year> + <year>1996</year><year>2017</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -126,6 +126,12 @@ ok</pre> <seealso marker="#error_report/1"><c>error_report/1</c></seealso> instead.</p> </warning> + <warning> + <p>If the Unicode translation modifier (<c>t</c>) is used in + the format string, all error handlers must ensure that the + formatted output is correctly encoded for the I/O + device.</p> + </warning> </desc> </func> <func> @@ -163,6 +169,19 @@ ok</pre> </desc> </func> <func> + <name name="get_format_depth" arity="0"/> + <fsummary>Get the value of the Kernel application variable + <c>error_logger_format_depth</c>.</fsummary> + <desc> + <p>Returns <c>max(10, Depth)</c>, where <c>Depth</c> is the + value of + <seealso marker="kernel:kernel_app#error_logger_format_depth"> + error_logger_format_depth</seealso> + in the Kernel application, if Depth is an integer. Otherwise, + <c>unlimited</c> is returned.</p> + </desc> + </func> + <func> <name name="info_msg" arity="1"/> <name name="info_msg" arity="2"/> <fsummary>Send a standard information event to the error logger.</fsummary> @@ -184,6 +203,12 @@ ok</pre> the standard event handler, meaning no further events are logged. When in doubt, use <c>info_report/1</c> instead.</p> </warning> + <warning> + <p>If the Unicode translation modifier (<c>t</c>) is used in + the format string, all error handlers must ensure that the + formatted output is correctly encoded for the I/O + device.</p> + </warning> </desc> </func> <func> @@ -249,7 +274,7 @@ ok</pre> successful, or <c>{error, allready_have_logfile}</c> if logging to file is already enabled, or an error tuple if another error occurred (for example, if <c><anno>Filename</anno></c> - cannot be opened).</p> + cannot be opened). The file is opened with encoding UTF-8.</p> </item> <tag><c>close</c></tag> <item> @@ -332,6 +357,12 @@ ok</pre> the standard event handler, meaning no further events are logged. When in doubt, use <c>warning_report/1</c> instead.</p> </warning> + <warning> + <p>If the Unicode translation modifier (<c>t</c>) is used in + the format string, all error handlers must ensure that the + formatted output is correctly encoded for the I/O + device.</p> + </warning> </desc> </func> <func> diff --git a/lib/kernel/doc/src/inet.xml b/lib/kernel/doc/src/inet.xml index b7c904ff45..b71e8a1e5d 100644 --- a/lib/kernel/doc/src/inet.xml +++ b/lib/kernel/doc/src/inet.xml @@ -75,8 +75,8 @@ Address ip_address() ------- ------------ ::1 {0,0,0,0,0,0,0,1} ::192.168.42.2 {0,0,0,0,0,0,(192 bsl 8) bor 168,(42 bsl 8) bor 2} -FFFF::192.168.42.2 - {16#FFFF,0,0,0,0,0,(192 bsl 8) bor 168,(42 bsl 8) bor 2} +::FFFF:192.168.42.2 + {0,0,0,0,0,16#FFFF,(192 bsl 8) bor 168,(42 bsl 8) bor 2} 3ffe:b80:1f8d:2:204:acff:fe17:bf38 {16#3ffe,16#b80,16#1f8d,16#2,16#204,16#acff,16#fe17,16#bf38} fe80::204:acff:fe17:bf38 @@ -87,8 +87,8 @@ fe80::204:acff:fe17:bf38 <pre> 1> <input>inet:parse_address("192.168.42.2").</input> {ok,{192,168,42,2}} -2> <input>inet:parse_address("FFFF::192.168.42.2").</input> -{ok,{65535,0,0,0,0,0,49320,10754}}</pre> +2> <input>inet:parse_address("::FFFF:192.168.42.2").</input> +{ok,{0,0,0,0,0,65535,49320,10754}}</pre> </description> <datatypes> diff --git a/lib/kernel/doc/src/kernel_app.xml b/lib/kernel/doc/src/kernel_app.xml index 9fccb4c7ac..e5ac031539 100644 --- a/lib/kernel/doc/src/kernel_app.xml +++ b/lib/kernel/doc/src/kernel_app.xml @@ -58,6 +58,7 @@ </section> <section> + <marker id="erl_signal_server"/> <title>OS Signal Event Handler</title> <p>Asynchronous OS signals may be subscribed to via the Kernel applications event manager (see <seealso marker="doc/design_principles:des_princ">OTP Design Principles</seealso> and @@ -185,7 +186,7 @@ <tag><c>{file, FileName}</c></tag> <item><p>Installs the standard event handler, which prints error reports to file <c>FileName</c>, where <c>FileName</c> - is a string.</p></item> + is a string. The file is opened with encoding UTF-8.</p></item> <tag><c>false</c></tag> <item> <p>No standard event handler is installed, but diff --git a/lib/kernel/doc/src/net_kernel.xml b/lib/kernel/doc/src/net_kernel.xml index 4e2b0c69db..0b94fc0fa6 100644 --- a/lib/kernel/doc/src/net_kernel.xml +++ b/lib/kernel/doc/src/net_kernel.xml @@ -4,7 +4,7 @@ <erlref> <header> <copyright> - <year>1996</year><year>2016</year> + <year>1996</year><year>2017</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -64,6 +64,19 @@ $ <input>erl -sname foobar</input></pre> by the magic cookie system, see section <seealso marker="doc/reference_manual:distributed">Distributed Erlang</seealso> in the Erlang Reference Manual.</p> + <warning> + <p> + Starting a distributed node without also specifying + <seealso marker="erts:erl#proto_dist"><c>-proto_dist inet_tls</c></seealso> + will expose the node to attacks that may give the attacker + complete access to the node and in extension the cluster. + When using un-secure distributed nodes, make sure that the + network is configured to keep potential attackers out. + See the <seealso marker="ssl:ssl_distribution"> + Using SSL for Erlang Distribution</seealso> User's Guide + for details on how to setup a secure distributed node. + </p> + </warning> </description> <funcs> diff --git a/lib/kernel/doc/src/notes.xml b/lib/kernel/doc/src/notes.xml index 7127a59a0c..e1cf45109d 100644 --- a/lib/kernel/doc/src/notes.xml +++ b/lib/kernel/doc/src/notes.xml @@ -31,6 +31,161 @@ </header> <p>This document describes the changes made to the Kernel application.</p> +<section><title>Kernel 5.3</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p>Function <c>inet:ntoa/1</c> has been fixed to return + lowercase letters according to RFC 5935 that has been + approved after this function was written. Previously + uppercase letters were returned so this may be a + backwards incompatible change depending on how the + returned address string is used.</p> + <p>Function <c>inet:parse_address/1</c> has been fixed to + accept %-suffixes on scoped addresses. The addresses does + not work yet, but gives no parse errors.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-13006 Aux Id: ERIERL-20, ERL-429 </p> + </item> + <item> + <p> + Fix bug where gethostname would incorrectly fail with + enametoolong on Linux.</p> + <p> + Own Id: OTP-14310</p> + </item> + <item> + <p> + Fix bug causing <c>code:is_module_native</c> to falsely + return true when <c>local</c> call trace is enabled for + the module.</p> + <p> + Own Id: OTP-14390</p> + </item> + <item> + <p> + Add early reject of invalid node names from distributed + nodes.</p> + <p> + Own Id: OTP-14426</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Since Unicode is now allowed in atoms an extra check is + needed for node names, which are restricted to Latin-1.</p> + <p> + Own Id: OTP-13805</p> + </item> + <item> + <p>Replaced usage of deprecated symbolic <seealso + marker="erts:erlang#type-time_unit"><c>time + unit</c></seealso> representations.</p> + <p> + Own Id: OTP-13831 Aux Id: OTP-13735 </p> + </item> + <item> + <p><c>file:write_file(Name, Data, [raw])</c> would turn + <c>Data</c> into a single binary before writing. This + meant it could not take advantage of the <c>writev()</c> + system call if it was given a list of binaries and told + to write with <c>raw</c> mode.</p> + <p> + Own Id: OTP-13909</p> + </item> + <item> + <p>The performance of the <c>disk_log</c> has been + somewhat improved in some corner cases (big items), and + the documentation has been clarified. </p> + <p> + Own Id: OTP-14057 Aux Id: PR-1245 </p> + </item> + <item> + <p>Functions for detecting changed code has been added. + <c>code:modified_modules/0</c> returns all currently + loaded modules that have changed on disk. + <c>code:module_status/1</c> returns the status for a + module. In the shell and in <c>c</c> module, <c>mm/0</c> + is short for <c>code:modified_modules/0</c>, and + <c>lm/0</c> reloads all currently loaded modules that + have changed on disk.</p> + <p> + Own Id: OTP-14059</p> + </item> + <item> + <p> + Introduce an event manager in Erlang to handle OS + signals. A subset of OS signals may be subscribed to and + those are described in the Kernel application.</p> + <p> + Own Id: OTP-14186</p> + </item> + <item> + <p> Sockets can now be bound to device (SO_BINDTODEVICE) + on platforms where it is supported. </p> <p> This has + been implemented e.g to support VRF-Lite under Linux; see + <url + href="https://www.kernel.org/doc/Documentation/networking/vrf.txt"> + VRF </url>, and GitHub pull request <url + href="https://github.com/erlang/otp/pull/1326">#1326</url>. + </p> + <p> + Own Id: OTP-14357 Aux Id: PR-1326 </p> + </item> + <item> + <p> + Added option to store shell_history on disk so that the + history can be reused between sessions.</p> + <p> + Own Id: OTP-14409 Aux Id: PR-1420 </p> + </item> + <item> + <p> The size of crash reports created by + <c>gen_server</c>, <c>gen_statem</c> and <c>proc_lib</c> + is limited with aid of the Kernel application variable + <c>error_logger_format_depth</c>. The purpose is to limit + the size of the messages sent to the <c>error_logger</c> + process when processes with huge message queues or states + crash. </p> <p>The crash report generated by + <c>proc_lib</c> includes the new tag + <c>message_queue_len</c>. The neighbour report also + includes the new tag <c>current_stacktrace</c>. Finally, + the neighbour report no longer includes the tags + <c>messages</c> and <c>dictionary</c>. </p> <p> The new + function <c>error_logger:get_format_depth/0</c> can be + used to retrieve the value of the Kernel application + variable <c>error_logger_format_depth</c>. </p> + <p> + Own Id: OTP-14417</p> + </item> + <item> + <p> One of the ETS tables used by the <c>global</c> + module is created with <c>{read_concurrency, true}</c> in + order to reduce contention. </p> + <p> + Own Id: OTP-14419</p> + </item> + <item> + <p> + Warnings have been added to the relevant documentation + about not using un-secure distributed nodes in exposed + environments.</p> + <p> + Own Id: OTP-14425</p> + </item> + </list> + </section> + +</section> + <section><title>Kernel 5.2</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/kernel/doc/src/os.xml b/lib/kernel/doc/src/os.xml index 64c5cbe571..0e9add4161 100644 --- a/lib/kernel/doc/src/os.xml +++ b/lib/kernel/doc/src/os.xml @@ -174,8 +174,9 @@ DirOut = os:cmd("dir"), % on Win32 platform</code> <tag><c>handle</c></tag> <item> - This signal will notify <c>erl_signal_server</c> when it is received by - the Erlang runtime system. + This signal will notify + <seealso marker="kernel_app#erl_signal_server"><c>erl_signal_server</c></seealso> + when it is received by the Erlang runtime system. </item> </taglist> </desc> diff --git a/lib/kernel/src/Makefile b/lib/kernel/src/Makefile index 78aa6192a9..5946620f0f 100644 --- a/lib/kernel/src/Makefile +++ b/lib/kernel/src/Makefile @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 1996-2016. All Rights Reserved. +# Copyright Ericsson AB 1996-2017. 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. diff --git a/lib/kernel/src/disk_log_1.erl b/lib/kernel/src/disk_log_1.erl index 10c22e1ad6..93856aa7b3 100644 --- a/lib/kernel/src/disk_log_1.erl +++ b/lib/kernel/src/disk_log_1.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2016. All Rights Reserved. +%% Copyright Ericsson AB 1997-2017. 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. diff --git a/lib/kernel/src/dist_util.erl b/lib/kernel/src/dist_util.erl index 1c326afca8..b3507e5d13 100644 --- a/lib/kernel/src/dist_util.erl +++ b/lib/kernel/src/dist_util.erl @@ -572,12 +572,25 @@ recv_name(#hs_data{socket = Socket, f_recv = Recv}) -> ?shutdown(no_node) end. -get_name([$n,VersionA, VersionB, Flag1, Flag2, Flag3, Flag4 | OtherNode]) -> - {?u32(Flag1, Flag2, Flag3, Flag4), list_to_atom(OtherNode), - ?u16(VersionA,VersionB)}; +get_name([$n,VersionA, VersionB, Flag1, Flag2, Flag3, Flag4 | OtherNode] = Data) -> + case is_valid_name(OtherNode) of + true -> + {?u32(Flag1, Flag2, Flag3, Flag4), list_to_atom(OtherNode), + ?u16(VersionA,VersionB)}; + false -> + ?shutdown(Data) + end; get_name(Data) -> ?shutdown(Data). +is_valid_name(OtherNodeName) -> + case string:lexemes(OtherNodeName,"@") of + [_OtherNodeName,_OtherNodeHost] -> + true; + _else -> + false + end. + publish_type(Flags) -> case Flags band ?DFLAG_PUBLISHED of 0 -> diff --git a/lib/kernel/src/error_logger.erl b/lib/kernel/src/error_logger.erl index 81f1bf8d97..9bf8547745 100644 --- a/lib/kernel/src/error_logger.erl +++ b/lib/kernel/src/error_logger.erl @@ -31,6 +31,8 @@ handle_event/2, handle_call/2, handle_info/2, terminate/2]). +-export([get_format_depth/0, limit_term/1]). + -define(buffer_size, 10). %%----------------------------------------------------------------- @@ -518,3 +520,21 @@ string_p1([H|T]) when is_list(H) -> end; string_p1([]) -> true; string_p1(_) -> false. + +-spec limit_term(term()) -> term(). + +limit_term(Term) -> + case get_format_depth() of + unlimited -> Term; + D -> io_lib:limit_term(Term, D) + end. + +-spec get_format_depth() -> 'unlimited' | pos_integer(). + +get_format_depth() -> + case application:get_env(kernel, error_logger_format_depth) of + {ok, Depth} when is_integer(Depth) -> + max(10, Depth); + undefined -> + unlimited + end. diff --git a/lib/kernel/src/global.erl b/lib/kernel/src/global.erl index 3d6415036c..a9e92b28b8 100644 --- a/lib/kernel/src/global.erl +++ b/lib/kernel/src/global.erl @@ -447,7 +447,8 @@ info() -> init([]) -> process_flag(trap_exit, true), _ = ets:new(global_locks, [set, named_table, protected]), - _ = ets:new(global_names, [set, named_table, protected]), + _ = ets:new(global_names, [set, named_table, protected, + {read_concurrency, true}]), _ = ets:new(global_names_ext, [set, named_table, protected]), _ = ets:new(global_pid_names, [bag, named_table, protected]), diff --git a/lib/kernel/src/group.erl b/lib/kernel/src/group.erl index 0eeaaad8d2..bf785959ff 100644 --- a/lib/kernel/src/group.erl +++ b/lib/kernel/src/group.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2016. All Rights Reserved. +%% Copyright Ericsson AB 1996-2017. 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. diff --git a/lib/kernel/src/group_history.erl b/lib/kernel/src/group_history.erl index 5ca5e2d1dd..91f3663cc5 100644 --- a/lib/kernel/src/group_history.erl +++ b/lib/kernel/src/group_history.erl @@ -218,7 +218,7 @@ handle_open_error({invalid_header, Term}) -> [Term]); handle_open_error({file_error, FileName, Reason}) -> show('$#erlang-history-file-error', - "Error handling File ~s. Reason: ~p~n" + "Error handling File ~ts. Reason: ~p~n" "History logging will be disabled.~n", [FileName, Reason]); handle_open_error(Err) -> @@ -309,7 +309,7 @@ show_rename_warning() -> show_invalid_file_warning(FileName) -> show('$#erlang-history-invalid-file', - "Shell history expects to be able to use the file ~s " + "Shell history expects to be able to use the file ~ts " "which currently exists and is not a file usable for " "history logging purposes. History logging will be " "disabled.~n", [FileName]). diff --git a/lib/kernel/src/inet_parse.erl b/lib/kernel/src/inet_parse.erl index 0f5dc40553..29804dc50b 100644 --- a/lib/kernel/src/inet_parse.erl +++ b/lib/kernel/src/inet_parse.erl @@ -644,8 +644,12 @@ ipv6_addr(Cs) -> ipv6_addr(hex(Cs), [], 0). %% Before "::" +ipv6_addr({Cs0,"%"++Cs1}, A, N) when N == 7 -> + ipv6_addr_scope(Cs1, [hex_to_int(Cs0)|A], [], N+1, []); ipv6_addr({Cs0,[]}, A, N) when N == 7 -> ipv6_addr_done([hex_to_int(Cs0)|A]); +ipv6_addr({Cs0,"::%"++Cs1}, A, N) when N =< 6 -> + ipv6_addr_scope(Cs1, [hex_to_int(Cs0)|A], [], N+1, []); ipv6_addr({Cs0,"::"}, A, N) when N =< 6 -> ipv6_addr_done([hex_to_int(Cs0)|A], [], N+1); ipv6_addr({Cs0,"::"++Cs1}, A, N) when N =< 5 -> @@ -658,6 +662,8 @@ ipv6_addr(_, _, _) -> erlang:error(badarg). %% After "::" +ipv6_addr({Cs0,"%"++Cs1}, A, B, N) when N =< 6 -> + ipv6_addr_scope(Cs1, A, [hex_to_int(Cs0)|B], N+1, []); ipv6_addr({Cs0,[]}, A, B, N) when N =< 6 -> ipv6_addr_done(A, [hex_to_int(Cs0)|B], N+1); ipv6_addr({Cs0,":"++Cs1}, A, B, N) when N =< 5 -> @@ -667,6 +673,43 @@ ipv6_addr({Cs0,"."++_=Cs1}, A, B, N) when N =< 5 -> ipv6_addr(_, _, _, _) -> erlang:error(badarg). +%% After "%" +ipv6_addr_scope([], Ar, Br, N, Sr) -> + ScopeId = + case lists:reverse(Sr) of + %% Empty scope id + "" -> 0; + %% Scope id starts with 0 + "0"++S -> dec16(S); + _ -> 0 + end, + %% Suggested formats for scope id parsing: + %% "" -> "0" + %% "0" -> Scope id 0 + %% "1" - "9", "10" - "99" -> "0"++S + %% "0"++DecimalScopeId -> decimal scope id + %% "25"++PercentEncoded -> Percent encoded interface name + %% S -> Interface name (Unicode?) + %% Missing: translation from interface name into integer scope id. + %% XXX: scope id is actually 32 bit, but we only have room for + %% 16 bit in the second address word - ignore or fix (how)? + ipv6_addr_scope(ScopeId, Ar, Br, N); +ipv6_addr_scope([C|Cs], Ar, Br, N, Sr) -> + ipv6_addr_scope(Cs, Ar, Br, N, [C|Sr]). +%% +ipv6_addr_scope(ScopeId, [P], Br, N) + when N =< 7, P =:= 16#fe80; + N =< 7, P =:= 16#ff02 -> + %% Optimized special case + ipv6_addr_done([ScopeId,P], Br, N+1); +ipv6_addr_scope(ScopeId, Ar, Br, N) -> + case lists:reverse(Br++dup(8-N, 0, Ar)) of + [P,0|Xs] when P =:= 16#fe80; P =:= 16#ff02 -> + list_to_tuple([P,ScopeId|Xs]); + _ -> + erlang:error(badarg) + end. + ipv6_addr_done(Ar, Br, N, {D1,D2,D3,D4}) -> ipv6_addr_done(Ar, [((D3 bsl 8) bor D4),((D1 bsl 8) bor D2)|Br], N+2). @@ -690,6 +733,19 @@ hex(Cs, [_|_]=R, _) when is_list(Cs) -> hex(_, _, _) -> erlang:error(badarg). +%% Parse a reverse decimal integer string, empty is 0 +dec16(Cs) -> dec16(Cs, 0). +%% +dec16([], I) -> I; +dec16([C|Cs], I) when C >= $0, C =< $9 -> + case 10*I + (C - $0) of + J when 16#ffff < J -> + erlang:error(badarg); + J -> + dec16(Cs, J) + end; +dec16(_, _) -> erlang:error(badarg). + %% Hex string to integer hex_to_int(Cs) -> erlang:list_to_integer(Cs, 16). @@ -703,7 +759,7 @@ dup(N, E, L) when is_integer(N), N >= 1 -> %% Convert IPv4 address to ascii %% Convert IPv6 / IPV4 address to ascii (plain format) -ntoa({A,B,C,D}) -> +ntoa({A,B,C,D}) when (A band B band C band D band (bnot 16#ff)) =:= 0 -> integer_to_list(A) ++ "." ++ integer_to_list(B) ++ "." ++ integer_to_list(C) ++ "." ++ integer_to_list(D); %% ANY @@ -711,13 +767,25 @@ ntoa({0,0,0,0,0,0,0,0}) -> "::"; %% LOOPBACK ntoa({0,0,0,0,0,0,0,1}) -> "::1"; %% IPV4 ipv6 host address -ntoa({0,0,0,0,0,0,A,B}) -> "::" ++ dig_to_dec(A) ++ "." ++ dig_to_dec(B); +ntoa({0,0,0,0,0,0,A,B}) when (A band B band (bnot 16#ffff)) =:= 0 -> + "::" ++ dig_to_dec(A) ++ "." ++ dig_to_dec(B); %% IPV4 non ipv6 host address -ntoa({0,0,0,0,0,16#ffff,A,B}) -> - "::FFFF:" ++ dig_to_dec(A) ++ "." ++ dig_to_dec(B); -ntoa({_,_,_,_,_,_,_,_}=T) -> - %% Find longest sequence of zeros, at least 2, to replace with "::" - ntoa(tuple_to_list(T), []); +ntoa({0,0,0,0,0,16#ffff,A,B}) when (A band B band (bnot 16#ffff)) =:= 0 -> + "::ffff:" ++ dig_to_dec(A) ++ "." ++ dig_to_dec(B); +ntoa({A,B,C,D,E,F,G,H}) + when (A band B band C band D band E band F band G band H band + (bnot 16#ffff)) =:= 0 -> + if + A =:= 16#fe80, B =/= 0; + A =:= 16#ff02, B =/= 0 -> + %% Find longest sequence of zeros, at least 2, + %% to replace with "::" + ntoa([A,0,C,D,E,F,G,H], []) ++ "%0" ++ integer_to_list(B); + true -> + %% Find longest sequence of zeros, at least 2, + %% to replace with "::" + ntoa([A,B,C,D,E,F,G,H], []) + end; ntoa(_) -> {error, einval}. @@ -780,9 +848,19 @@ dig_to_dec(X) -> integer_to_list((X bsr 8) band 16#ff) ++ "." ++ integer_to_list(X band 16#ff). -%% Convert a integer to hex string -dig_to_hex(X) -> - erlang:integer_to_list(X, 16). +%% Convert a integer to hex string (lowercase) +dig_to_hex(0) -> "0"; +dig_to_hex(X) when is_integer(X), 0 < X -> + dig_to_hex(X, ""). +%% +dig_to_hex(0, Acc) -> Acc; +dig_to_hex(X, Acc) -> + dig_to_hex( + X bsr 4, + [case X band 15 of + D when D < 10 -> D + $0; + D -> D - 10 + $a + end|Acc]). %% %% Count number of '.' in a name diff --git a/lib/kernel/src/inet_tcp_dist.erl b/lib/kernel/src/inet_tcp_dist.erl index 8c8fe86811..e3fdb1bb22 100644 --- a/lib/kernel/src/inet_tcp_dist.erl +++ b/lib/kernel/src/inet_tcp_dist.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2016. All Rights Reserved. +%% Copyright Ericsson AB 1997-2017. 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. @@ -390,14 +390,14 @@ splitnode(Driver, Node, LongOrShortNames) -> error_msg("** System running to use " "fully qualified " "hostnames **~n" - "** Hostname ~s is illegal **~n", + "** Hostname ~ts is illegal **~n", [Host]), ?shutdown(Node) end; L when length(L) > 1, LongOrShortNames =:= shortnames -> error_msg("** System NOT running to use fully qualified " "hostnames **~n" - "** Hostname ~s is illegal **~n", + "** Hostname ~ts is illegal **~n", [Host]), ?shutdown(Node); _ -> diff --git a/lib/kernel/src/kernel.app.src b/lib/kernel/src/kernel.app.src index 7aefbbd9b6..2a11b04310 100644 --- a/lib/kernel/src/kernel.app.src +++ b/lib/kernel/src/kernel.app.src @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2016. All Rights Reserved. +%% Copyright Ericsson AB 1996-2017. 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. diff --git a/lib/kernel/test/code_SUITE.erl b/lib/kernel/test/code_SUITE.erl index 7831777726..6f8e949aac 100644 --- a/lib/kernel/test/code_SUITE.erl +++ b/lib/kernel/test/code_SUITE.erl @@ -107,14 +107,19 @@ init_per_testcase(big_boot_embedded, Config) -> _Else -> {skip, "Needs crypto!"} end; -init_per_testcase(on_load_embedded, Config) -> +init_per_testcase(on_load_embedded, Config0) -> LibRoot = code:lib_dir(), LinkName = filename:join(LibRoot, "on_load_app-1.0"), - [{link_name,LinkName}|Config]; + Config = [{link_name,LinkName}|Config0], + init_per_testcase(Config); init_per_testcase(_Func, Config) -> + init_per_testcase(Config). + +init_per_testcase(Config) -> P = code:get_path(), [{code_path, P}|Config]. + end_per_testcase(module_status, Config) -> code:purge(?TESTMOD), code:delete(?TESTMOD), @@ -1786,6 +1791,19 @@ do_normalized_paths([]) -> %% Test that module_status/1 behaves as expected module_status(_Config) -> + case test_server:is_cover() of + true -> + module_status(); + false -> + %% Make sure that we terminate the cover server. + try + module_status() + after + cover:stop() + end + end. + +module_status() -> %% basics not_loaded = code:module_status(fubar), % nonexisting {file, preloaded} = code:is_loaded(erlang), diff --git a/lib/kernel/test/disk_log_SUITE.erl b/lib/kernel/test/disk_log_SUITE.erl index 2b11a0381f..fe2fc778f2 100644 --- a/lib/kernel/test/disk_log_SUITE.erl +++ b/lib/kernel/test/disk_log_SUITE.erl @@ -481,7 +481,7 @@ halt_ro_crash(Conf) when is_list(Conf) -> %% This is how it was before R6B: %% {C1,T1,15} = disk_log:chunk(a,start), %% {C2,T2} = disk_log:chunk(a,C1), - {C1,_OneItem,7476} = disk_log:chunk(a,start), + {C1,_OneItem,7478} = disk_log:chunk(a,start), {C2, [], 7} = disk_log:chunk(a,C1), eof = disk_log:chunk(a,C2), ok = disk_log:close(a), @@ -2503,8 +2503,8 @@ error_repair(Conf) when is_list(Conf) -> ok = disk_log:close(n), BadFile = add_ext(File, 2), % current file set_opened(BadFile), - crash(BadFile, 26), % the binary is now invalid - {repaired,n,{recovered,0},{badbytes,24}} = + crash(BadFile, 28), % the binary is now invalid + {repaired,n,{recovered,0},{badbytes,26}} = disk_log:open([{name, n}, {file, File}, {type, wrap}, {format, internal}, {size, {40,No}}]), ok = disk_log:close(n), @@ -2521,8 +2521,8 @@ error_repair(Conf) when is_list(Conf) -> ok = disk_log:close(n), BadFile2 = add_ext(File, 1), % current file set_opened(BadFile2), - crash(BadFile2, 47), % the second binary is now invalid - {repaired,n,{recovered,1},{badbytes,24}} = + crash(BadFile2, 51), % the second binary is now invalid + {repaired,n,{recovered,1},{badbytes,26}} = disk_log:open([{name, n}, {file, File}, {type, wrap}, {format, internal}, {size, {4000,No}}]), ok = disk_log:close(n), @@ -2580,7 +2580,7 @@ error_repair(Conf) when is_list(Conf) -> ok = disk_log:close(n), set_opened(File), crash(File, 30), - {repaired,n,{recovered,3},{badbytes,15}} = + {repaired,n,{recovered,3},{badbytes,16}} = disk_log:open([{name, n}, {file, File}, {type, halt}, {format, internal},{repair,true}, {quiet, true}, {head_func, {?MODULE, head_fun, [{ok,"head"}]}}]), @@ -2807,7 +2807,7 @@ chunk(Conf) when is_list(Conf) -> ok = disk_log:log_terms(n, [{some,terms}]), % second file full 2 = curf(n), BadFile = add_ext(File, 1), - crash(BadFile, 26), % the _binary_ is now invalid + crash(BadFile, 28), % the _binary_ is now invalid {error, {corrupt_log_file, BFile}} = disk_log:chunk(n, start, 1), BadFile = BFile, ok = disk_log:close(n), @@ -2817,7 +2817,7 @@ chunk(Conf) when is_list(Conf) -> {format, internal}]), ok = disk_log:log_terms(n, [{this,is}]), ok = disk_log:sync(n), - crash(File, 26), % the _binary_ is now invalid + crash(File, 28), % the _binary_ is now invalid {error, {corrupt_log_file, File2}} = disk_log:chunk(n, start, 1), crash(File, 10), {error,{corrupt_log_file,_}} = disk_log:bchunk(n, start, 1), @@ -2911,8 +2911,8 @@ chunk(Conf) when is_list(Conf) -> {ok, n} = disk_log:open([{name, n}, {file, File}, {type, wrap}, {format, internal}, {mode, read_only}]), CrashFile = add_ext(File, 1), - crash(CrashFile, 46), % the binary term {some,terms} is now bad - {H1, [{this,is}], 16} = disk_log:chunk(n, start, 10), + crash(CrashFile, 51), % the binary term {some,terms} is now bad + {H1, [{this,is}], 18} = disk_log:chunk(n, start, 10), {H2, [{on,a},{wrap,file}]} = disk_log:chunk(n, H1), eof = disk_log:chunk(n, H2), ok = disk_log:close(n), @@ -2926,8 +2926,8 @@ chunk(Conf) when is_list(Conf) -> ok = disk_log:close(n), {ok, n} = disk_log:open([{name, n}, {file, File}, {type, halt}, {format, internal}, {mode, read_only}]), - crash(File, 46), % the binary term {some,terms} is now bad - {J1, [{this,is}], 16} = disk_log:chunk(n, start, 10), + crash(File, 51), % the binary term {some,terms} is now bad + {J1, [{this,is}], 18} = disk_log:chunk(n, start, 10), {J2, [{on,a},{halt,file}]} = disk_log:chunk(n, J1), eof = disk_log:chunk(n, J2), ok = disk_log:close(n), @@ -2942,8 +2942,8 @@ chunk(Conf) when is_list(Conf) -> ok = disk_log:close(n), {ok, n} = disk_log:open([{name, n}, {file, File}, {type, halt}, {format, internal}, {mode, read_only}]), - crash(File, 40), % the binary term {s} is now bad - {J11, [{this,is}], 6} = disk_log:chunk(n, start, 10), + crash(File, 44), % the binary term {s} is now bad + {J11, [{this,is}], 7} = disk_log:chunk(n, start, 10), {J21, [{on,a},{halt,file}]} = disk_log:chunk(n, J11), eof = disk_log:chunk(n, J21), ok = disk_log:close(n), @@ -3062,7 +3062,7 @@ truncate(Conf) when is_list(Conf) -> ok = disk_log:truncate(n, apa), rec(1, {disk_log, node(), n, {truncated, 6}}), {0, 0} = no_overflows(n), - 22 = curb(n), + 23 = curb(n), 1 = curf(n), 1 = cur_cnt(n), true = (Size == sz(n)), @@ -3082,7 +3082,7 @@ truncate(Conf) when is_list(Conf) -> ok = disk_log:truncate(n, apa), rec(1, {disk_log, node(), n, {truncated, 3}}), {0, 0} = no_overflows(n), - 22 = curb(n), + 23 = curb(n), 1 = curf(n), 1 = cur_cnt(n), true = (Size == sz(n)), @@ -3191,45 +3191,45 @@ info_current(Conf) when is_list(Conf) -> %% Internal with header. {ok, n} = disk_log:open([{name, n}, {file, File}, {type, wrap}, {head, header}, {size, {100,No}}]), - {25, 1} = {curb(n), cur_cnt(n)}, + {26, 1} = {curb(n), cur_cnt(n)}, {1, 1} = {no_written_items(n), no_items(n)}, ok = disk_log:log(n, B), - {93, 2} = {curb(n), cur_cnt(n)}, + {94, 2} = {curb(n), cur_cnt(n)}, {2, 2} = {no_written_items(n), no_items(n)}, ok = disk_log:close(n), {ok, n} = disk_log:open([{name, n}, {file, File}, {type, wrap}, {notify, true}, {head, header}, {size, {100,No}}]), - {93, 2} = {curb(n), cur_cnt(n)}, + {94, 2} = {curb(n), cur_cnt(n)}, {0, 2} = {no_written_items(n), no_items(n)}, ok = disk_log:log(n, B), rec(1, {disk_log, node(), n, {wrap, 0}}), - {93, 2} = {curb(n), cur_cnt(n)}, + {94, 2} = {curb(n), cur_cnt(n)}, {2, 4} = {no_written_items(n), no_items(n)}, disk_log:inc_wrap_file(n), rec(1, {disk_log, node(), n, {wrap, 0}}), - {25, 1} = {curb(n), cur_cnt(n)}, + {26, 1} = {curb(n), cur_cnt(n)}, {3, 4} = {no_written_items(n), no_items(n)}, ok = disk_log:log_terms(n, [B,B,B]), %% Used to be one message, but now one per wrapped file. rec(1, {disk_log, node(), n, {wrap, 0}}), rec(1, {disk_log, node(), n, {wrap, 2}}), - {93, 2} = {curb(n), cur_cnt(n)}, + {94, 2} = {curb(n), cur_cnt(n)}, {8, 7} = {no_written_items(n), no_items(n)}, ok = disk_log:log_terms(n, [B]), rec(1, {disk_log, node(), n, {wrap, 2}}), ok = disk_log:log_terms(n, [B]), rec(1, {disk_log, node(), n, {wrap, 2}}), - {93, 2} = {curb(n), cur_cnt(n)}, + {94, 2} = {curb(n), cur_cnt(n)}, {12, 7} = {no_written_items(n), no_items(n)}, ok = disk_log:log_terms(n, [BB,BB]), %% Used to be one message, but now one per wrapped file. rec(2, {disk_log, node(), n, {wrap, 2}}), - {193, 2} = {curb(n), cur_cnt(n)}, + {194, 2} = {curb(n), cur_cnt(n)}, {16, 7} = {no_written_items(n), no_items(n)}, ok = disk_log:log_terms(n, [SB,SB,SB]), rec(1, {disk_log, node(), n, {wrap, 2}}), - {79, 4} = {curb(n), cur_cnt(n)}, + {80, 4} = {curb(n), cur_cnt(n)}, {20, 9} = {no_written_items(n), no_items(n)}, ok = disk_log:close(n), del(File, No), diff --git a/lib/kernel/test/erl_distribution_SUITE.erl b/lib/kernel/test/erl_distribution_SUITE.erl index d7a9ac39a3..bbfaa9d147 100644 --- a/lib/kernel/test/erl_distribution_SUITE.erl +++ b/lib/kernel/test/erl_distribution_SUITE.erl @@ -230,7 +230,7 @@ legal(Name) -> end. illegal(Name) -> - case test_node(Name) of + case test_node(Name, true) of not_started -> ok; started -> @@ -238,12 +238,20 @@ illegal(Name) -> end. test_node(Name) -> + test_node(Name, false). +test_node(Name, Illigal) -> ProgName = atom_to_list(lib:progname()), Command = ProgName ++ " -noinput " ++ long_or_short() ++ Name ++ - " -eval \"net_adm:ping('" ++ atom_to_list(node()) ++ "')\"", + " -eval \"net_adm:ping('" ++ atom_to_list(node()) ++ "')\"" ++ + case Illigal of + true -> + " -eval \"timer:sleep(10000),init:stop().\""; + false -> + "" + end, net_kernel:monitor_nodes(true), BinCommand = unicode:characters_to_binary(Command, utf8), - open_port({spawn, BinCommand}, [stream]), + Prt = open_port({spawn, BinCommand}, [stream]), Node = list_to_atom(Name), receive {nodeup, Node} -> diff --git a/lib/kernel/test/gen_tcp_api_SUITE.erl b/lib/kernel/test/gen_tcp_api_SUITE.erl index 92a74465b7..12d22519ce 100644 --- a/lib/kernel/test/gen_tcp_api_SUITE.erl +++ b/lib/kernel/test/gen_tcp_api_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1998-2016. All Rights Reserved. +%% Copyright Ericsson AB 1998-2017. 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. @@ -302,9 +302,9 @@ t_implicit_inet6(Config) when is_list(Config) -> end. t_implicit_inet6(Host, Addr) -> - case gen_tcp:listen(0, [inet6]) of + Loopback = {0,0,0,0,0,0,0,1}, + case gen_tcp:listen(0, [inet6, {ip,Loopback}]) of {ok,S1} -> - Loopback = {0,0,0,0,0,0,0,1}, io:format("~s ~p~n", ["::1",Loopback]), implicit_inet6(S1, Loopback), ok = gen_tcp:close(S1), @@ -524,10 +524,10 @@ local_handshake(S, SAddr, C, CAddr) -> t_accept_inet6_tclass(Config) when is_list(Config) -> TClassOpt = {tclass,8#56 bsl 2}, % Expedited forwarding - case gen_tcp:listen(0, [inet6,TClassOpt]) of + Loopback = {0,0,0,0,0,0,0,1}, + case gen_tcp:listen(0, [inet6, {ip, Loopback}, TClassOpt]) of {ok,L} -> LPort = ok(inet:port(L)), - Loopback = {0,0,0,0,0,0,0,1}, Sa = ok(gen_tcp:connect(Loopback, LPort, [])), Sb = ok(gen_tcp:accept(L)), [TClassOpt] = ok(inet:getopts(Sb, [tclass])), diff --git a/lib/kernel/test/gen_tcp_misc_SUITE.erl b/lib/kernel/test/gen_tcp_misc_SUITE.erl index 929f66d400..331864b5de 100644 --- a/lib/kernel/test/gen_tcp_misc_SUITE.erl +++ b/lib/kernel/test/gen_tcp_misc_SUITE.erl @@ -50,9 +50,8 @@ killing_acceptor/1,killing_multi_acceptors/1,killing_multi_acceptors2/1, several_accepts_in_one_go/1, accept_system_limit/1, active_once_closed/1, send_timeout/1, send_timeout_active/1, - otp_7731/1, zombie_sockets/1, otp_7816/1, otp_8102/1, - wrapping_oct/0, wrapping_oct/1, - otp_9389/1]). + otp_7731/1, zombie_sockets/1, otp_7816/1, otp_8102/1, + wrapping_oct/0, wrapping_oct/1, otp_9389/1, otp_13939/1]). %% Internal exports. -export([sender/3, not_owner/1, passive_sockets_server/2, priority_server/1, @@ -3014,3 +3013,42 @@ ok({ok,V}) -> V. get_hostname(Name) -> "@"++Host = lists:dropwhile(fun(C) -> C =/= $@ end, atom_to_list(Name)), Host. + +otp_13939(doc) -> + ["Check that writing to a remotely closed socket doesn't block forever " + "when exit_on_close is false."]; +otp_13939(suite) -> + []; +otp_13939(Config) when is_list(Config) -> + {Pid, Ref} = spawn_opt( + fun() -> + {ok, Listener} = gen_tcp:listen(0, [{exit_on_close, false}]), + {ok, Port} = inet:port(Listener), + + spawn_link( + fun() -> + {ok, Client} = gen_tcp:connect("localhost", Port, + [{active, false}]), + ok = gen_tcp:close(Client) + end), + + {ok, Accepted} = gen_tcp:accept(Listener), + + ok = gen_tcp:send(Accepted, <<0:(10*1024*1024*8)>>), + + %% The bug surfaces when there's a delay between the send + %% operations; inet:getstat is a red herring. + timer:sleep(100), + + {error, Code} = gen_tcp:send(Accepted, <<0:(10*1024*1024*8)>>), + ct:pal("gen_tcp:send returned ~p~n", [Code]) + end, [link, monitor]), + + receive + {'DOWN', Ref, process, Pid, normal} -> + ok + after 1000 -> + demonitor(Ref, [flush]), + exit(Pid, normal), + ct:fail("Server process blocked on send.") + end. diff --git a/lib/kernel/test/gen_udp_SUITE.erl b/lib/kernel/test/gen_udp_SUITE.erl index 1029d7ef0a..aa616d43d6 100644 --- a/lib/kernel/test/gen_udp_SUITE.erl +++ b/lib/kernel/test/gen_udp_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1998-2016. All Rights Reserved. +%% Copyright Ericsson AB 1998-2017. 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. @@ -717,9 +717,9 @@ implicit_inet6(Config) when is_list(Config) -> implicit_inet6(Host, Addr) -> Active = {active,false}, - case gen_udp:open(0, [inet6,Active]) of + Loopback = {0,0,0,0,0,0,0,1}, + case gen_udp:open(0, [inet6,Active,{ip, Loopback}]) of {ok,S1} -> - Loopback = {0,0,0,0,0,0,0,1}, io:format("~s ~p~n", ["::1",Loopback]), implicit_inet6(S1, Active, Loopback), ok = gen_udp:close(S1), diff --git a/lib/kernel/test/inet_SUITE.erl b/lib/kernel/test/inet_SUITE.erl index 97f789b61c..3b502be8b8 100644 --- a/lib/kernel/test/inet_SUITE.erl +++ b/lib/kernel/test/inet_SUITE.erl @@ -447,91 +447,125 @@ parse_hosts(Config) when is_list(Config) -> inet_parse:resolv(ResolvErr1). parse_address(Config) when is_list(Config) -> - V4Strict = + V4Reversable = [{{0,0,0,0},"0.0.0.0"}, - {{1,2,3,4},"1.2.3.4"}, + {{1,2,3,4},"1.2.3.4"}, {{253,252,251,250},"253.252.251.250"}, {{1,2,255,254},"1.2.255.254"}], - V6Strict = + V6Reversable = [{{0,0,0,0,0,0,0,0},"::"}, + {{0,0,0,0,0,0,0,1},"::1"}, + {{0,0,0,0,0,0,0,2},"::0.0.0.2"}, {{15,0,0,0,0,0,0,2},"f::2"}, - {{15,16#f11,0,0,0,0,256,2},"f:f11::0100:2"}, - {{0,0,0,0,0,0,0,16#17},"::17"}, - {{16#700,0,0,0,0,0,0,0},"0700::"}, - {{0,0,0,0,0,0,2,1},"::2:1"}, + {{15,16#f11,0,0,0,0,256,2},"f:f11::100:2"}, + {{16#700,0,0,0,0,0,0,0},"700::"}, + {{0,0,0,0,0,0,2,1},"::0.2.0.1"}, {{0,0,0,0,0,3,2,1},"::3:2:1"}, {{0,0,0,0,4,3,2,1},"::4:3:2:1"}, {{0,0,0,5,4,3,2,1},"::5:4:3:2:1"}, {{0,0,6,5,4,3,2,1},"::6:5:4:3:2:1"}, - {{0,7,6,5,4,3,2,1},"::7:6:5:4:3:2:1"}, + {{0,7,6,5,4,3,2,1},"0:7:6:5:4:3:2:1"}, {{7,0,0,0,0,0,0,0},"7::"}, {{7,6,0,0,0,0,0,0},"7:6::"}, {{7,6,5,0,0,0,0,0},"7:6:5::"}, {{7,6,5,4,0,0,0,0},"7:6:5:4::"}, {{7,6,5,4,3,0,0,0},"7:6:5:4:3::"}, {{7,6,5,4,3,2,0,0},"7:6:5:4:3:2::"}, - {{7,6,5,4,3,2,1,0},"7:6:5:4:3:2:1::"}, + {{7,6,5,4,3,2,1,0},"7:6:5:4:3:2:1:0"}, + {{0,0,6,5,4,3,0,0},"::6:5:4:3:0:0"}, + {{0,0,6,5,4,0,0,0},"0:0:6:5:4::"}, + {{8,0,0,5,4,0,0,1},"8::5:4:0:0:1"}, + {{8,0,0,5,0,0,0,1},"8:0:0:5::1"}, + {{0,7,6,5,4,3,2,0},"0:7:6:5:4:3:2:0"}, + {{0,0,6,5,4,3,0,0},"::6:5:4:3:0:0"}, + {{0,0,0,5,4,0,0,0},"::5:4:0:0:0"}, + {{0,0,0,0,4,0,0,0},"::4:0:0:0"}, + {{0,0,0,5,0,0,0,0},"0:0:0:5::"}, {{16#c11,16#c22,16#5c33,16#c440,16#55c0,16#c66c,16#77,16#88}, - "c11:0c22:5c33:c440:55c0:c66c:77:0088"}, + "c11:c22:5c33:c440:55c0:c66c:77:88"}, + {{0,16#c22,16#5c33,16#c440,16#55c0,16#c66c,16#77,16#88}, + "0:c22:5c33:c440:55c0:c66c:77:88"}, {{16#c11,0,16#5c33,16#c440,16#55c0,16#c66c,16#77,16#88}, - "c11::5c33:c440:55c0:c66c:77:0088"}, + "c11:0:5c33:c440:55c0:c66c:77:88"}, {{16#c11,16#c22,0,16#c440,16#55c0,16#c66c,16#77,16#88}, - "c11:0c22::c440:55c0:c66c:77:0088"}, + "c11:c22:0:c440:55c0:c66c:77:88"}, {{16#c11,16#c22,16#5c33,0,16#55c0,16#c66c,16#77,16#88}, - "c11:0c22:5c33::55c0:c66c:77:0088"}, + "c11:c22:5c33:0:55c0:c66c:77:88"}, {{16#c11,16#c22,16#5c33,16#c440,0,16#c66c,16#77,16#88}, - "c11:0c22:5c33:c440::c66c:77:0088"}, + "c11:c22:5c33:c440:0:c66c:77:88"}, {{16#c11,16#c22,16#5c33,16#c440,16#55c0,0,16#77,16#88}, - "c11:0c22:5c33:c440:55c0::77:0088"}, + "c11:c22:5c33:c440:55c0:0:77:88"}, {{16#c11,16#c22,16#5c33,16#c440,16#55c0,16#c66c,0,16#88}, - "c11:0c22:5c33:c440:55c0:c66c::0088"}, + "c11:c22:5c33:c440:55c0:c66c:0:88"}, + {{16#c11,16#c22,16#5c33,16#c440,16#55c0,16#c66c,16#77,0}, + "c11:c22:5c33:c440:55c0:c66c:77:0"}, + {{0,0,16#5c33,16#c440,16#55c0,16#c66c,16#77,16#88}, + "::5c33:c440:55c0:c66c:77:88"}, {{16#c11,0,0,16#c440,16#55c0,16#c66c,16#77,16#88}, - "c11::c440:55c0:c66c:77:0088"}, + "c11::c440:55c0:c66c:77:88"}, {{16#c11,16#c22,0,0,16#55c0,16#c66c,16#77,16#88}, - "c11:0c22::55c0:c66c:77:0088"}, + "c11:c22::55c0:c66c:77:88"}, {{16#c11,16#c22,16#5c33,0,0,16#c66c,16#77,16#88}, - "c11:0c22:5c33::c66c:77:0088"}, + "c11:c22:5c33::c66c:77:88"}, {{16#c11,16#c22,16#5c33,16#c440,0,0,16#77,16#88}, - "c11:0c22:5c33:c440::77:0088"}, + "c11:c22:5c33:c440::77:88"}, {{16#c11,16#c22,16#5c33,16#c440,16#55c0,0,0,16#88}, - "c11:0c22:5c33:c440:55c0::0088"}, + "c11:c22:5c33:c440:55c0::88"}, + {{16#c11,16#c22,16#5c33,16#c440,16#55c0,16#c66c,0,0}, + "c11:c22:5c33:c440:55c0:c66c::"}, + {{0,0,0,16#c440,16#55c0,16#c66c,16#77,16#88}, + "::c440:55c0:c66c:77:88"}, {{16#c11,0,0,0,16#55c0,16#c66c,16#77,16#88}, - "c11::55c0:c66c:77:0088"}, + "c11::55c0:c66c:77:88"}, {{16#c11,16#c22,0,0,0,16#c66c,16#77,16#88}, - "c11:0c22::c66c:77:0088"}, + "c11:c22::c66c:77:88"}, {{16#c11,16#c22,16#5c33,0,0,0,16#77,16#88}, - "c11:0c22:5c33::77:0088"}, + "c11:c22:5c33::77:88"}, {{16#c11,16#c22,16#5c33,16#c440,0,0,0,16#88}, - "c11:0c22:5c33:c440::0088"}, + "c11:c22:5c33:c440::88"}, + {{16#c11,16#c22,16#5c33,16#c440,16#55c0,0,0,0}, + "c11:c22:5c33:c440:55c0::"}, + {{0,0,0,0,16#55c0,16#c66c,16#77,16#88}, + "::55c0:c66c:77:88"}, {{16#c11,0,0,0,0,16#c66c,16#77,16#88}, - "c11::c66c:77:0088"}, + "c11::c66c:77:88"}, {{16#c11,16#c22,0,0,0,0,16#77,16#88}, - "c11:0c22::77:0088"}, + "c11:c22::77:88"}, {{16#c11,16#c22,16#5c33,0,0,0,0,16#88}, - "c11:0c22:5c33::0088"}, + "c11:c22:5c33::88"}, + {{16#c11,16#c22,16#5c33,16#c440,0,0,0,0}, + "c11:c22:5c33:c440::"}, + {{0,0,0,0,0,16#c66c,16#77,16#88}, + "::c66c:77:88"}, {{16#c11,0,0,0,0,0,16#77,16#88}, - "c11::77:0088"}, + "c11::77:88"}, {{16#c11,16#c22,0,0,0,0,0,16#88}, - "c11:0c22::0088"}, - {{0,0,0,0,0,65535,258,65534},"::FFFF:1.2.255.254"}, + "c11:c22::88"}, + {{16#c11,16#c22,16#5c33,0,0,0,0,0}, + "c11:c22:5c33::"}, + {{0,0,0,0,0,65535,258,65534},"::ffff:1.2.255.254"}, + {{16#fe80,12345,0,0,0,0,0,16#12},"fe80::12%012345"}, {{16#ffff,16#ffff,16#ffff,16#ffff,16#ffff,16#ffff,16#ffff,16#ffff}, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"} - |[{{D2,0,0,0,0,P,(D1 bsl 8) bor D2,(D3 bsl 8) bor D4}, - erlang:integer_to_list(D2, 16)++"::"++Q++S} - || {{D1,D2,D3,D4},S} <- V4Strict, - {P,Q} <- [{0,""},{16#17,"17:"},{16#ff0,"0ff0:"}]]], + |[{list_to_tuple(P++[(D1 bsl 8) bor D2,(D3 bsl 8) bor D4]), + Q++S} + || {{D1,D2,D3,D4},S} <- + tl(V4Reversable), + {P,Q} <- + [{[0,0,0,0,0,16#ffff],"::ffff:"}, + {[0,0,0,0,0,0],"::"}]]], V4Sloppy = [{{10,1,16#98,16#76},"10.0x019876"}, {{8#12,1,8#130,8#321},"012.01.054321"}, - {{255,255,255,255},"255.255.255.0377"}, - {{255,255,255,255},"0Xff.000000000377.0x0000ff.255"}, - {{255,255,255,255},"255.255.65535"}, - {{255,255,255,255},"255.0xFF.0177777"}, - {{255,255,255,255},"255.16777215"}, - {{255,255,255,255},"00377.0XFFFFFF"}, - {{255,255,255,255},"4294967295"}, - {{255,255,255,255},"0xffffffff"}, - {{255,255,255,255},"00000000000037777777777"}, + {{252,253,254,255},"252.253.254.0377"}, + {{252,253,254,255},"0Xfc.000000000375.0x0000fe.255"}, + {{252,253,254,255},"252.253.65279"}, + {{252,253,254,255},"252.0xFD.0177377"}, + {{252,253,254,255},"252.16645887"}, + {{252,253,254,255},"00374.0XFDFEFF"}, + {{252,253,254,255},"4244504319"}, + {{252,253,254,255},"0xfcfdfeff"}, + {{252,253,254,255},"00000000000037477377377"}, {{16#12,16#34,16#56,16#78},"0x12345678"}, {{16#12,16#34,16#56,16#78},"0x12.0x345678"}, {{16#12,16#34,16#56,16#78},"0x12.0X34.0x5678"}, @@ -543,8 +577,14 @@ parse_address(Config) when is_list(Config) -> {{0,0,0,0},"0.00.0.0"}, {{0,0,0,0},"0.0.000000000000.0"}], V6Sloppy = - [{{0,0,0,0,0,65535,(D1 bsl 8) bor D2,(D3 bsl 8) bor D4},S} - || {{D1,D2,D3,D4},S} <- V4Strict++V4Sloppy], + [{{16#a,16#b,16#c,16#0,16#0,16#d,16#e,16#f},"A:B:C::d:e:f"}, + {{16#fe80,0,0,0,0,0,0,16#12},"fe80::12%XXXXXXX"}] + ++ + [{{P,0,0,0,0,D2,(D1 bsl 8) bor D2,(D3 bsl 8) bor D4}, + Q++erlang:integer_to_list(D2, 16)++":"++S} + || {{D1,D2,D3,D4},S} <- V4Reversable, + {P,Q} <- + [{16#2001,"2001::"},{16#177,"177::"},{16#ff0,"Ff0::"}]], V4Err = ["0.256.0.1", "1.2.3.4.5", @@ -588,28 +628,36 @@ parse_address(Config) when is_list(Config) -> "fec0::fFfF:127.0.0.1."], t_parse_address (parse_ipv6_address, - V6Strict++V6Sloppy++V6Err++V4Err), + false, + V6Reversable++V6Sloppy++V6Err++V4Err), t_parse_address (parse_ipv6strict_address, - V6Strict++V6Err++V4Err++[S || {_,S} <- V6Sloppy]), + true, + V6Reversable++V6Err++V4Err), t_parse_address (parse_ipv4_address, - V4Strict++V4Sloppy++V4Err++V6Err++[S || {_,S} <- V6Strict]), + false, + V4Reversable++V4Sloppy++V4Err++V6Err++[S || {_,S} <- V6Reversable]), t_parse_address (parse_ipv4strict_address, - V4Strict++V4Err++V6Err++[S || {_,S} <- V4Sloppy++V6Strict]). + true, + V4Reversable++V4Err++V6Err++[S || {_,S} <- V4Sloppy++V6Reversable]). -t_parse_address(Func, []) -> +t_parse_address(Func, _Reversable, []) -> io:format("~p done.~n", [Func]), ok; -t_parse_address(Func, [{Addr,String}|L]) -> +t_parse_address(Func, Reversable, [{Addr,String}|L]) -> io:format("~p = ~p.~n", [Addr,String]), {ok,Addr} = inet:Func(String), - t_parse_address(Func, L); -t_parse_address(Func, [String|L]) -> + case Reversable of + true ->String = inet:ntoa(Addr); + false -> ok + end, + t_parse_address(Func, Reversable, L); +t_parse_address(Func, Reversable, [String|L]) -> io:format("~p.~n", [String]), {error,einval} = inet:Func(String), - t_parse_address(Func, L). + t_parse_address(Func, Reversable, L). parse_strict_address(Config) when is_list(Config) -> {ok, {127,0,0,1}} = diff --git a/lib/kernel/test/inet_sockopt_SUITE.erl b/lib/kernel/test/inet_sockopt_SUITE.erl index 322b9f30fe..ada9c2689c 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-2016. All Rights Reserved. +%% Copyright Ericsson AB 2007-2017. 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. @@ -620,7 +620,7 @@ ipv6_v6only_close(Module, Socket) -> %% Test using socket option ipv6_v6only for UDP. use_ipv6_v6only_udp(Config) when is_list(Config) -> - case gen_udp:open(0, [inet6,{ipv6_v6only,true}]) of + case gen_udp:open(0, [inet6,{ip,{0,0,0,0,0,0,0,1}}, {ipv6_v6only,true}]) of {ok,S6} -> case inet:getopts(S6, [ipv6_v6only]) of {ok,[{ipv6_v6only,true}]} -> diff --git a/lib/kernel/test/os_SUITE.erl b/lib/kernel/test/os_SUITE.erl index 3cbb75a633..53a9e168ef 100644 --- a/lib/kernel/test/os_SUITE.erl +++ b/lib/kernel/test/os_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2016. All Rights Reserved. +%% Copyright Ericsson AB 1997-2017. 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. @@ -319,31 +319,38 @@ perf_counter_api(_Config) -> true = is_integer(os:perf_counter()), true = os:perf_counter() > 0, - T1 = os:perf_counter(), + Conv = fun(T1, T2) -> + erlang:convert_time_unit(T2 - T1, perf_counter, nanosecond) + end, + + do_perf_counter_test([], Conv, 120000000, 80000000), + do_perf_counter_test([1000], fun(T1, T2) -> T2 - T1 end, 120, 80). + +do_perf_counter_test(CntArgs, Conv, Upper, Lower) -> + %% We run the test multiple times to try to get a somewhat + %% stable value... what does this test? That the + %% calculate_perf_counter_unit in sys_time.c works somewhat ok. + do_perf_counter_test(CntArgs, Conv, Upper, Lower, 10). + +do_perf_counter_test(CntArgs, _Conv, Upper, Lower, 0) -> + ct:fail("perf_counter_test ~p ~p ~p",[CntArgs, Upper, Lower]); +do_perf_counter_test(CntArgs, Conv, Upper, Lower, Iters) -> + + T1 = apply(os, perf_counter, CntArgs), timer:sleep(100), - T2 = os:perf_counter(), - TsDiff = erlang:convert_time_unit(T2 - T1, perf_counter, nanosecond), - ct:pal("T1: ~p~n" + T2 = apply(os, perf_counter, CntArgs), + TsDiff = Conv(T1, T2), + ct:log("T1: ~p~n" "T2: ~p~n" "TsDiff: ~p~n", [T1,T2,TsDiff]), - %% We allow a 15% diff - true = TsDiff < 115000000, - true = TsDiff > 85000000, - - T1Ms = os:perf_counter(1000), - timer:sleep(100), - T2Ms = os:perf_counter(1000), - MsDiff = T2Ms - T1Ms, - ct:pal("T1Ms: ~p~n" - "T2Ms: ~p~n" - "MsDiff: ~p~n", - [T1Ms,T2Ms,MsDiff]), - - %% We allow a 15% diff - true = MsDiff < 115, - true = MsDiff > 85. + if + TsDiff < Upper, TsDiff > Lower -> + ok; + true -> + do_perf_counter_test(CntArgs, Conv, Upper, Lower, Iters-1) + end. %% Util functions diff --git a/lib/kernel/test/sendfile_SUITE.erl b/lib/kernel/test/sendfile_SUITE.erl index 2673c38494..bfa564c32c 100644 --- a/lib/kernel/test/sendfile_SUITE.erl +++ b/lib/kernel/test/sendfile_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2011-2016. All Rights Reserved. +%% Copyright Ericsson AB 2011-2017. 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. @@ -100,13 +100,13 @@ init_per_testcase(TC,Config) when TC == t_sendfile_recvduring; %% Check if sendfile is supported on this platform case catch sendfile_send(Send) of ok -> - Config; + init_per_testcase(t_sendfile, Config); Error -> ct:log("Error: ~p",[Error]), {skip,"Not supported"} end; init_per_testcase(_Tc,Config) -> - Config. + Config ++ [{sendfile_opts,[{use_threads,false}]}]. t_sendfile_small(Config) when is_list(Config) -> diff --git a/lib/kernel/vsn.mk b/lib/kernel/vsn.mk index 76b020e8ed..4edecd8969 100644 --- a/lib/kernel/vsn.mk +++ b/lib/kernel/vsn.mk @@ -1 +1 @@ -KERNEL_VSN = 5.2 +KERNEL_VSN = 5.3 |