aboutsummaryrefslogtreecommitdiffstats
path: root/lib/kernel/src
diff options
context:
space:
mode:
Diffstat (limited to 'lib/kernel/src')
-rw-r--r--lib/kernel/src/Makefile2
-rw-r--r--lib/kernel/src/disk_log_1.erl2
-rw-r--r--lib/kernel/src/dist_util.erl19
-rw-r--r--lib/kernel/src/error_logger.erl20
-rw-r--r--lib/kernel/src/global.erl3
-rw-r--r--lib/kernel/src/group.erl2
-rw-r--r--lib/kernel/src/group_history.erl4
-rw-r--r--lib/kernel/src/inet_parse.erl98
-rw-r--r--lib/kernel/src/inet_tcp_dist.erl6
-rw-r--r--lib/kernel/src/kernel.app.src2
10 files changed, 135 insertions, 23 deletions
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 1128ee3ec5..e150938487 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.