diff options
Diffstat (limited to 'lib/kernel/src')
26 files changed, 287 insertions, 341 deletions
diff --git a/lib/kernel/src/Makefile b/lib/kernel/src/Makefile index c76ff9e2f0..eaced4861a 100644 --- a/lib/kernel/src/Makefile +++ b/lib/kernel/src/Makefile @@ -107,7 +107,6 @@ MODULES = \ net_adm \ net_kernel \ os \ - packages \ pg2 \ ram_file \ rpc \ @@ -171,13 +170,13 @@ docs: # ---------------------------------------------------- ../../hipe/main/hipe.hrl: ../../hipe/vsn.mk ../../hipe/main/hipe.hrl.src - sed -e "s;%VSN%;$(HIPE_VSN);" ../../hipe/main/hipe.hrl.src > ../../hipe/main/hipe.hrl + $(vsn_verbose)sed -e "s;%VSN%;$(HIPE_VSN);" ../../hipe/main/hipe.hrl.src > ../../hipe/main/hipe.hrl $(APP_TARGET): $(APP_SRC) ../vsn.mk - sed -e 's;%VSN%;$(KERNEL_VSN);' $< > $@ + $(vsn_verbose)sed -e 's;%VSN%;$(KERNEL_VSN);' $< > $@ $(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk - sed -e 's;%VSN%;$(KERNEL_VSN);' $< > $@ + $(vsn_verbose)sed -e 's;%VSN%;$(KERNEL_VSN);' $< > $@ EPMD_FLAGS = -Depmd_port_no=$(EPMD_PORT_NO) \ @@ -187,10 +186,10 @@ EPMD_FLAGS = -Depmd_port_no=$(EPMD_PORT_NO) \ -Derlang_daemon_port=$(EPMD_PORT_NO) $(ESRC)/inet_dns_record_adts.hrl: $(ESRC)/inet_dns_record_adts.pl - LANG=C $(PERL) $< > $@ + $(gen_verbose)LANG=C $(PERL) $< > $@ $(EBIN)/erl_epmd.beam: $(ESRC)/erl_epmd.erl - $(ERLC) $(ERL_COMPILE_FLAGS) $(EPMD_FLAGS) -o$(EBIN) $< + $(V_ERLC) $(ERL_COMPILE_FLAGS) $(EPMD_FLAGS) -o$(EBIN) $< # ---------------------------------------------------- # Release Target diff --git a/lib/kernel/src/application.erl b/lib/kernel/src/application.erl index 9b7c4aa7b8..4e65883be7 100644 --- a/lib/kernel/src/application.erl +++ b/lib/kernel/src/application.erl @@ -23,7 +23,7 @@ which_applications/0, which_applications/1, loaded_applications/0, permit/2]). -export([set_env/3, set_env/4, unset_env/2, unset_env/3]). --export([get_env/1, get_env/2, get_all_env/0, get_all_env/1]). +-export([get_env/1, get_env/2, get_env/3, get_all_env/0, get_all_env/1]). -export([get_key/1, get_key/2, get_all_key/0, get_all_key/1]). -export([get_application/0, get_application/1, info/0]). -export([start_type/0]). @@ -264,6 +264,20 @@ get_env(Key) -> get_env(Application, Key) -> application_controller:get_env(Application, Key). +-spec get_env(Application, Par, Def) -> Val when + Application :: atom(), + Par :: atom(), + Def :: term(), + Val :: term(). + +get_env(Application, Key, Def) -> + case get_env(Application, Key) of + {ok, Val} -> + Val; + undefined -> + Def + end. + -spec get_all_env() -> Env when Env :: [{Par :: atom(), Val :: term()}]. diff --git a/lib/kernel/src/application_controller.erl b/lib/kernel/src/application_controller.erl index 68cd26ec10..75ce852001 100644 --- a/lib/kernel/src/application_controller.erl +++ b/lib/kernel/src/application_controller.erl @@ -1960,5 +1960,5 @@ to_string(Term) -> true -> Term; false -> - lists:flatten(io_lib:write(Term)) + lists:flatten(io_lib:format("~134217728p", [Term])) end. diff --git a/lib/kernel/src/code.erl b/lib/kernel/src/code.erl index c808ac7cb7..361f2bdf8a 100644 --- a/lib/kernel/src/code.erl +++ b/lib/kernel/src/code.erl @@ -359,7 +359,6 @@ load_code_server_prerequisites() -> hipe_unified_loader, lists, os, - packages, unicode], [M = M:module_info(module) || M <- Needed], ok. @@ -413,7 +412,7 @@ which(Module) when is_atom(Module) -> end. which2(Module) -> - Base = to_path(Module), + Base = atom_to_list(Module), File = filename:basename(Base) ++ objfile_extension(), Path = get_path(), which(File, filename:dirname(Base), Path). @@ -547,9 +546,6 @@ has_ext(Ext, Extlen, File) -> _ -> false end. -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), diff --git a/lib/kernel/src/code_server.erl b/lib/kernel/src/code_server.erl index 00ad923466..b2d2c19f78 100644 --- a/lib/kernel/src/code_server.erl +++ b/lib/kernel/src/code_server.erl @@ -1229,7 +1229,7 @@ load_abs(File, Mod0, Caller, St) -> end. try_load_module(Mod, Dir, Caller, St) -> - File = filename:append(Dir, to_path(Mod) ++ + File = filename:append(Dir, to_list(Mod) ++ objfile_extension()), case erl_prim_loader:get_file(File) of error -> @@ -1347,7 +1347,7 @@ load_file_1(Mod, Caller, #state{cache=Cache}=St0) -> end. mod_to_bin([Dir|Tail], Mod) -> - File = filename:append(Dir, to_path(Mod) ++ objfile_extension()), + File = filename:append(Dir, to_list(Mod) ++ objfile_extension()), case erl_prim_loader:get_file(File) of error -> mod_to_bin(Tail, Mod); @@ -1356,7 +1356,7 @@ mod_to_bin([Dir|Tail], Mod) -> end; mod_to_bin([], Mod) -> %% At last, try also erl_prim_loader's own method - File = to_path(Mod) ++ objfile_extension(), + File = to_list(Mod) ++ objfile_extension(), case erl_prim_loader:get_file(File) of error -> error; % No more alternatives ! @@ -1570,6 +1570,3 @@ to_list(X) when is_atom(X) -> atom_to_list(X). to_atom(X) when is_atom(X) -> X; to_atom(X) when is_list(X) -> list_to_atom(X). - -to_path(X) -> - filename:join(packages:split(X)). diff --git a/lib/kernel/src/disk_log.erl b/lib/kernel/src/disk_log.erl index 5b1efcd395..1513fdaec0 100644 --- a/lib/kernel/src/disk_log.erl +++ b/lib/kernel/src/disk_log.erl @@ -44,6 +44,8 @@ %% To be used for debugging only: -export([pid2name/1]). +-export_type([continuation/0]). + -type dlog_state_error() :: 'ok' | {'error', term()}. -record(state, {queue = [], diff --git a/lib/kernel/src/dist_util.erl b/lib/kernel/src/dist_util.erl index f0d54a2f3e..e3511988a6 100644 --- a/lib/kernel/src/dist_util.erl +++ b/lib/kernel/src/dist_util.erl @@ -757,7 +757,8 @@ setup_timer(Pid, Timeout) -> end. reset_timer(Timer) -> - Timer ! {self(), reset}. + Timer ! {self(), reset}, + ok. cancel_timer(Timer) -> unlink(Timer), diff --git a/lib/kernel/src/erl_ddll.erl b/lib/kernel/src/erl_ddll.erl index f967fcc2ef..e03d280cd8 100644 --- a/lib/kernel/src/erl_ddll.erl +++ b/lib/kernel/src/erl_ddll.erl @@ -54,9 +54,7 @@ info(_, _) -> erlang:nif_error(undef). -spec format_error_int(ErrSpec) -> string() when - ErrSpec :: inconsisten | linked_in_driver | permanent - | not_loaded | not_loaded_by_this_process | not_pending - | already_loaded | unloading. + ErrSpec :: term(). format_error_int(_) -> erlang:nif_error(undef). diff --git a/lib/kernel/src/error_handler.erl b/lib/kernel/src/error_handler.erl index f8bc5f499c..a3aa1f1dcf 100644 --- a/lib/kernel/src/error_handler.erl +++ b/lib/kernel/src/error_handler.erl @@ -23,10 +23,12 @@ %% "error_handler: add no_native compiler directive" -compile(no_native). -%% A simple error handler. +%% Callbacks called from the run-time system. +-export([undefined_function/3,undefined_lambda/3,breakpoint/3]). --export([undefined_function/3, undefined_lambda/3, stub_function/3, - breakpoint/3]). +%% Exported utility functions. +-export([raise_undef_exception/3]). +-export([stub_function/3]). -spec undefined_function(Module, Function, Args) -> any() when @@ -41,12 +43,7 @@ undefined_function(Module, Func, Args) -> true -> apply(Module, Func, Args); false -> - case check_inheritance(Module, Args) of - {value, Base, Args1} -> - apply(Base, Func, Args1); - none -> - crash(Module, Func, Args) - end + call_undefined_function_handler(Module, Func, Args) end; {module, _} -> crash(Module, Func, Args); @@ -77,6 +74,14 @@ undefined_lambda(Module, Fun, Args) -> breakpoint(Module, Func, Args) -> (int()):eval(Module, Func, Args). +-spec raise_undef_exception(Module, Function, Args) -> no_return() when + Module :: atom(), + Function :: atom(), + Args :: list(). + +raise_undef_exception(Module, Func, Args) -> + crash({Module,Func,Args,[]}). + %% Used to make the call to the 'int' module a "weak" one, to avoid %% building strong components in xref or dialyzer. @@ -130,27 +135,11 @@ ensure_loaded(Module) -> stub_function(Mod, Func, Args) -> exit({undef,[{Mod,Func,Args,[]}]}). -check_inheritance(Module, Args) -> - Attrs = erlang:get_module_info(Module, attributes), - case lists:keyfind(extends, 1, Attrs) of - {extends, [Base]} when is_atom(Base), Base =/= Module -> - %% This is just a heuristic for detecting abstract modules - %% with inheritance so they can be handled; it would be - %% much better to do it in the emulator runtime - case lists:keyfind(abstract, 1, Attrs) of - {abstract, [true]} -> - case lists:reverse(Args) of - [M|Rs] when tuple_size(M) > 1, - element(1,M) =:= Module, - tuple_size(element(2,M)) > 0, - is_atom(element(1,element(2,M))) -> - {value, Base, lists:reverse(Rs, [element(2,M)])}; - _ -> - {value, Base, Args} - end; - _ -> - {value, Base, Args} - end; - _ -> - none +call_undefined_function_handler(Module, Func, Args) -> + Handler = '$handle_undefined_function', + case erlang:function_exported(Module, Handler, 2) of + false -> + crash(Module, Func, Args); + true -> + Module:Handler(Func, Args) end. diff --git a/lib/kernel/src/file.erl b/lib/kernel/src/file.erl index 22af38c598..16f2dde464 100644 --- a/lib/kernel/src/file.erl +++ b/lib/kernel/src/file.erl @@ -38,7 +38,7 @@ %% Specialized -export([ipread_s32bu_p32bu/3]). %% Generic file contents. --export([open/2, close/1, advise/4, +-export([open/2, close/1, advise/4, allocate/3, read/2, write/2, pread/2, pread/3, pwrite/2, pwrite/3, read_line/1, @@ -397,9 +397,10 @@ raw_write_file_info(Name, #file_info{} = Info) -> %% Contemporary mode specification - list of options --spec open(Filename, Modes) -> {ok, IoDevice} | {error, Reason} when +-spec open(File, Modes) -> {ok, IoDevice} | {error, Reason} when + File :: Filename | iodata(), Filename :: name(), - Modes :: [mode()], + Modes :: [mode() | ram], IoDevice :: io_device(), Reason :: posix() | badarg | system_limit. @@ -489,6 +490,18 @@ advise(#file_descriptor{module = Module} = Handle, Offset, Length, Advise) -> advise(_, _, _, _) -> {error, badarg}. +-spec allocate(File, Offset, Length) -> + 'ok' | {'error', posix()} when + File :: io_device(), + Offset :: non_neg_integer(), + Length :: non_neg_integer(). + +allocate(File, Offset, Length) when is_pid(File) -> + R = file_request(File, {allocate, Offset, Length}), + wait_file_reply(File, R); +allocate(#file_descriptor{module = Module} = Handle, Offset, Length) -> + Module:allocate(Handle, Offset, Length). + -spec read(IoDevice, Number) -> {ok, Data} | eof | {error, Reason} when IoDevice :: io_device() | atom(), Number :: non_neg_integer(), @@ -1314,6 +1327,7 @@ sendfile_send(Sock, Data, Old) -> %%% Helpers consult_stream(Fd) -> + _ = epp:set_encoding(Fd), consult_stream(Fd, 1, []). consult_stream(Fd, Line, Acc) -> @@ -1327,6 +1341,7 @@ consult_stream(Fd, Line, Acc) -> end. eval_stream(Fd, Handling, Bs) -> + _ = epp:set_encoding(Fd), eval_stream(Fd, Handling, 1, undefined, [], Bs). eval_stream(Fd, H, Line, Last, E, Bs) -> diff --git a/lib/kernel/src/file_io_server.erl b/lib/kernel/src/file_io_server.erl index 0bff56cf46..fad2ed7fb3 100644 --- a/lib/kernel/src/file_io_server.erl +++ b/lib/kernel/src/file_io_server.erl @@ -40,6 +40,8 @@ format_error({_Line, ?MODULE, Reason}) -> io_lib:format("~w", [Reason]); format_error({_Line, Mod, Reason}) -> Mod:format_error(Reason); +format_error(invalid_unicode) -> + io_lib:format("cannot translate from UTF-8", []); format_error(ErrorId) -> erl_posix_msg:message(ErrorId). @@ -209,6 +211,10 @@ file_request({advise,Offset,Length,Advise}, Reply -> {reply,Reply,State} end; +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{handle=Handle,buf=Buf,read_mode=ReadMode}=State) -> case position(Handle, At, Buf) of @@ -549,7 +555,7 @@ get_chars_notempty(Mod, Func, XtraArg, S, OutEnc, <<>> -> get_chars_apply(Mod, Func, XtraArg, S, OutEnc, State, eof); _ -> - {stop,invalid_unicode,{error,invalid_unicode},State} + {stop,invalid_unicode,invalid_unicode_error(Mod, Func, XtraArg, S),State} end; {error,Reason}=Error -> {stop,Reason,Error,State} @@ -616,12 +622,22 @@ get_chars_apply(Mod, Func, XtraArg, S0, OutEnc, end catch exit:ExReason -> - {stop,ExReason,{error,err_func(Mod, Func, XtraArg)},State}; + {stop,ExReason,invalid_unicode_error(Mod, Func, XtraArg, S0),State}; error:ErrReason -> {stop,ErrReason,{error,err_func(Mod, Func, XtraArg)},State} end. - +%% A hack that tries to inform the caller about the position where the +%% error occured. +invalid_unicode_error(Mod, Func, XtraArg, S) -> + try + {erl_scan,tokens,_Args} = XtraArg, + Location = erl_scan:continuation_location(S), + {error,{Location, ?MODULE, invalid_unicode},Location} + catch + _:_ -> + {error,err_func(Mod, Func, XtraArg)} + end. %% Convert error code to make it look as before err_func(io_lib, get_until, {_,F,_}) -> diff --git a/lib/kernel/src/gen_sctp.erl b/lib/kernel/src/gen_sctp.erl index 8fa963ec78..74ad192802 100644 --- a/lib/kernel/src/gen_sctp.erl +++ b/lib/kernel/src/gen_sctp.erl @@ -44,6 +44,7 @@ {priority, non_neg_integer()} | {recbuf, non_neg_integer()} | {reuseaddr, boolean()} | + {ipv6_v6only, boolean()} | {sctp_adaptation_layer, #sctp_setadaptation{}} | {sctp_associnfo, #sctp_assocparams{}} | {sctp_autoclose, non_neg_integer()} | @@ -72,6 +73,7 @@ priority | recbuf | reuseaddr | + ipv6_v6only | sctp_adaptation_layer | sctp_associnfo | sctp_autoclose | diff --git a/lib/kernel/src/gen_tcp.erl b/lib/kernel/src/gen_tcp.erl index e6dfdadb03..ec13ab6d2e 100644 --- a/lib/kernel/src/gen_tcp.erl +++ b/lib/kernel/src/gen_tcp.erl @@ -37,9 +37,11 @@ {dontroute, boolean()} | {exit_on_close, boolean()} | {header, non_neg_integer()} | + {high_msgq_watermark, pos_integer()} | {high_watermark, non_neg_integer()} | {keepalive, boolean()} | {linger, {boolean(), non_neg_integer()}} | + {low_msgq_watermark, pos_integer()} | {low_watermark, non_neg_integer()} | {mode, list | binary} | list | binary | {nodelay, boolean()} | @@ -57,7 +59,8 @@ {send_timeout, non_neg_integer() | infinity} | {send_timeout_close, boolean()} | {sndbuf, non_neg_integer()} | - {tos, non_neg_integer()}. + {tos, non_neg_integer()} | + {ipv6_v6only, boolean()}. -type option_name() :: active | buffer | @@ -66,9 +69,11 @@ dontroute | exit_on_close | header | + high_msgq_watermark | high_watermark | keepalive | linger | + low_msgq_watermark | low_watermark | mode | nodelay | @@ -85,7 +90,8 @@ send_timeout | send_timeout_close | sndbuf | - tos. + tos | + ipv6_v6only. -type connect_option() :: {ip, inet:ip_address()} | {fd, Fd :: non_neg_integer()} | diff --git a/lib/kernel/src/gen_udp.erl b/lib/kernel/src/gen_udp.erl index 830ca61b3c..c5a1173575 100644 --- a/lib/kernel/src/gen_udp.erl +++ b/lib/kernel/src/gen_udp.erl @@ -47,7 +47,8 @@ {recbuf, non_neg_integer()} | {reuseaddr, boolean()} | {sndbuf, non_neg_integer()} | - {tos, non_neg_integer()}. + {tos, non_neg_integer()} | + {ipv6_v6only, boolean()}. -type option_name() :: active | broadcast | @@ -69,7 +70,8 @@ recbuf | reuseaddr | sndbuf | - tos. + tos | + ipv6_v6only. -type socket() :: port(). -export_type([option/0, option_name/0]). diff --git a/lib/kernel/src/group.erl b/lib/kernel/src/group.erl index f92c6f7208..4d2e31a429 100644 --- a/lib/kernel/src/group.erl +++ b/lib/kernel/src/group.erl @@ -424,7 +424,7 @@ get_password_chars(Drv,Buf) -> end. get_chars(Prompt, M, F, Xa, Drv, Buf, Encoding) -> - Pbs = prompt_bytes(Prompt), + Pbs = prompt_bytes(Prompt, Encoding), get_chars_loop(Pbs, M, F, Xa, Drv, Buf, start, Encoding). get_chars_loop(Pbs, M, F, Xa, Drv, Buf0, State, Encoding) -> @@ -688,9 +688,9 @@ edit_password([Char|Cs],Chars) -> edit_password(Cs,[Char|Chars]). %% prompt_bytes(Prompt) -%% Return a flat list of bytes for the Prompt. -prompt_bytes(Prompt) -> - lists:flatten(io_lib:format_prompt(Prompt)). +%% Return a flat list of characters for the Prompt. +prompt_bytes(Prompt, Encoding) -> + lists:flatten(io_lib:format_prompt(Prompt, Encoding)). cast(L, binary,latin1) when is_list(L) -> list_to_binary(L); diff --git a/lib/kernel/src/heart.erl b/lib/kernel/src/heart.erl index 28452a377e..87cb9d7f51 100644 --- a/lib/kernel/src/heart.erl +++ b/lib/kernel/src/heart.erl @@ -42,9 +42,11 @@ -define(CLEAR_CMD, 5). -define(GET_CMD, 6). -define(HEART_CMD, 7). +-define(PREPARING_CRASH, 8). % Used in beam vm -define(TIMEOUT, 5000). -define(CYCLE_TIMEOUT, 10000). +-define(HEART_PORT_NAME, heart_port). %%--------------------------------------------------------------------- @@ -130,6 +132,8 @@ start_portprogram() -> Port when is_port(Port) -> case wait_ack(Port) of ok -> + %% register port so the vm can find it if need be + register(?HEART_PORT_NAME, Port), {ok, Port}; {error, Reason} -> report_problem({{port_problem, Reason}, @@ -225,6 +229,7 @@ no_reboot_shutdown(Port) -> end. do_cycle_port_program(Caller, Parent, Port, Cmd) -> + unregister(?HEART_PORT_NAME), case catch start_portprogram() of {ok, NewPort} -> send_shutdown(Port), diff --git a/lib/kernel/src/inet.erl b/lib/kernel/src/inet.erl index b4ebb1500c..9670271b2e 100644 --- a/lib/kernel/src/inet.erl +++ b/lib/kernel/src/inet.erl @@ -30,7 +30,9 @@ ifget/3, ifget/2, ifset/3, ifset/2, getstat/1, getstat/2, ip/1, stats/0, options/0, - pushf/3, popf/1, close/1, gethostname/0, gethostname/1]). + pushf/3, popf/1, close/1, gethostname/0, gethostname/1, + parse_ipv4_address/1, parse_ipv6_address/1, parse_ipv4strict_address/1, + parse_ipv6strict_address/1, parse_address/1, parse_strict_address/1]). -export([connect_options/2, listen_options/2, udp_options/2, sctp_options/2]). @@ -527,14 +529,57 @@ getservbyname(Name, Protocol) when is_atom(Name) -> Error -> Error end. +-spec parse_ipv4_address(Address) -> + {ok, IPv4Address} | {error, einval} when + Address :: string(), + IPv4Address :: ip_address(). +parse_ipv4_address(Addr) -> + inet_parse:ipv4_address(Addr). + +-spec parse_ipv6_address(Address) -> + {ok, IPv6Address} | {error, einval} when + Address :: string(), + IPv6Address :: ip_address(). +parse_ipv6_address(Addr) -> + inet_parse:ipv6_address(Addr). + +-spec parse_ipv4strict_address(Address) -> + {ok, IPv4Address} | {error, einval} when + Address :: string(), + IPv4Address :: ip_address(). +parse_ipv4strict_address(Addr) -> + inet_parse:ipv4strict_address(Addr). + +-spec parse_ipv6strict_address(Address) -> + {ok, IPv6Address} | {error, einval} when + Address :: string(), + IPv6Address :: ip_address(). +parse_ipv6strict_address(Addr) -> + inet_parse:ipv6strict_address(Addr). + +-spec parse_address(Address) -> + {ok, IPAddress} | {error, einval} when + Address :: string(), + IPAddress :: ip_address(). +parse_address(Addr) -> + inet_parse:address(Addr). + +-spec parse_strict_address(Address) -> + {ok, IPAddress} | {error, einval} when + Address :: string(), + IPAddress :: ip_address(). +parse_strict_address(Addr) -> + inet_parse:strict_address(Addr). + %% Return a list of available options options() -> [ tos, priority, reuseaddr, keepalive, dontroute, linger, - broadcast, sndbuf, recbuf, nodelay, + broadcast, sndbuf, recbuf, nodelay, ipv6_v6only, buffer, header, active, packet, deliver, mode, multicast_if, multicast_ttl, multicast_loop, exit_on_close, high_watermark, low_watermark, + high_msgq_watermark, low_msgq_watermark, send_timeout, send_timeout_close ]. @@ -552,8 +597,8 @@ stats() -> connect_options() -> [tos, priority, reuseaddr, keepalive, linger, sndbuf, recbuf, nodelay, header, active, packet, packet_size, buffer, mode, deliver, - exit_on_close, high_watermark, low_watermark, send_timeout, - send_timeout_close, delay_send,raw]. + exit_on_close, high_watermark, low_watermark, high_msgq_watermark, + low_msgq_watermark, send_timeout, send_timeout_close, delay_send, raw]. connect_options(Opts, Family) -> BaseOpts = @@ -607,9 +652,10 @@ con_add(Name, Val, R, Opts, AllOpts) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% listen_options() -> [tos, priority, reuseaddr, keepalive, linger, sndbuf, recbuf, nodelay, - header, active, packet, buffer, mode, deliver, backlog, - exit_on_close, high_watermark, low_watermark, send_timeout, - send_timeout_close, delay_send, packet_size,raw]. + header, active, packet, buffer, mode, deliver, backlog, ipv6_v6only, + exit_on_close, high_watermark, low_watermark, high_msgq_watermark, + low_msgq_watermark, send_timeout, send_timeout_close, delay_send, + packet_size, raw]. listen_options(Opts, Family) -> BaseOpts = @@ -664,7 +710,7 @@ list_add(Name, Val, R, Opts, As) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% udp_options() -> [tos, priority, reuseaddr, sndbuf, recbuf, header, active, buffer, mode, - deliver, + deliver, ipv6_v6only, broadcast, dontroute, multicast_if, multicast_ttl, multicast_loop, add_membership, drop_membership, read_packets,raw]. @@ -720,7 +766,7 @@ udp_add(Name, Val, R, Opts, As) -> sctp_options() -> [ % The following are generic inet options supported for SCTP sockets: mode, active, buffer, tos, priority, dontroute, reuseaddr, linger, sndbuf, - recbuf, + recbuf, ipv6_v6only, % Other options are SCTP-specific (though they may be similar to their % TCP and UDP counter-parts): diff --git a/lib/kernel/src/inet_int.hrl b/lib/kernel/src/inet_int.hrl index 467c4d5065..000119bc74 100644 --- a/lib/kernel/src/inet_int.hrl +++ b/lib/kernel/src/inet_int.hrl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2011. All Rights Reserved. +%% Copyright Ericsson AB 1997-2012. 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 @@ -124,6 +124,7 @@ -define(UDP_OPT_MULTICAST_LOOP, 13). -define(UDP_OPT_ADD_MEMBERSHIP, 14). -define(UDP_OPT_DROP_MEMBERSHIP, 15). +-define(INET_OPT_IPV6_V6ONLY, 16). % "Local" options: codes start from 20: -define(INET_LOPT_BUFFER, 20). -define(INET_LOPT_HEADER, 21). @@ -140,6 +141,8 @@ -define(INET_LOPT_READ_PACKETS, 33). -define(INET_OPT_RAW, 34). -define(INET_LOPT_TCP_SEND_TIMEOUT_CLOSE, 35). +-define(INET_LOPT_TCP_MSGQ_HIWTRMRK, 36). +-define(INET_LOPT_TCP_MSGQ_LOWTRMRK, 37). % Specific SCTP options: separate range: -define(SCTP_OPT_RTOINFO, 100). -define(SCTP_OPT_ASSOCINFO, 101). diff --git a/lib/kernel/src/inet_parse.erl b/lib/kernel/src/inet_parse.erl index ba62a59068..3551e701b6 100644 --- a/lib/kernel/src/inet_parse.erl +++ b/lib/kernel/src/inet_parse.erl @@ -36,7 +36,7 @@ -export([ipv4_address/1, ipv6_address/1]). -export([ipv4strict_address/1, ipv6strict_address/1]). --export([address/1]). +-export([address/1, strict_address/1]). -export([visible_string/1, domain/1]). -export([ntoa/1, dots/1]). -export([split_line/1]). @@ -456,6 +456,17 @@ address(Cs) when is_list(Cs) -> address(_) -> {error, einval}. +%%Parse ipv4 strict address or ipv6 strict address +strict_address(Cs) when is_list(Cs) -> + case ipv4strict_address(Cs) of + {ok,IP} -> + {ok,IP}; + _ -> + ipv6strict_address(Cs) + end; +strict_address(Cs) -> + {error, einval}. + %% %% Parse IPv4 address: %% d1.d2.d3.d4 diff --git a/lib/kernel/src/kernel.app.src b/lib/kernel/src/kernel.app.src index 17ab84c177..9a20baf8d0 100644 --- a/lib/kernel/src/kernel.app.src +++ b/lib/kernel/src/kernel.app.src @@ -28,7 +28,6 @@ application_starter, auth, code, - packages, code_server, dist_util, erl_boot_server, diff --git a/lib/kernel/src/packages.erl b/lib/kernel/src/packages.erl deleted file mode 100644 index e0b1f36b85..0000000000 --- a/lib/kernel/src/packages.erl +++ /dev/null @@ -1,158 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2002-2009. All Rights Reserved. -%% -%% The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved online at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% %CopyrightEnd% -%% --module(packages). - --export([to_string/1, concat/1, concat/2, is_valid/1, is_segmented/1, - split/1, last/1, first/1, strip_last/1, find_modules/1, - find_modules/2]). - -%% A package name (or a package-qualified module name) may be an atom or -%% a string (list of nonnegative integers) - not a deep list, and not a -%% list containing atoms. A name may be empty, but may not contain two -%% consecutive period (`.') characters or end with a period character. - --type package_name() :: atom() | string(). - --spec to_string(package_name()) -> string(). -to_string(Name) when is_atom(Name) -> - atom_to_list(Name); -to_string(Name) -> - Name. - -%% `concat' does not insert a leading period if the first segment is -%% empty. However, the result may contain leading, consecutive or -%% dangling period characters, if any of the segments after the first -%% are empty. Use 'is_valid' to check the result if necessary. - --spec concat(package_name(), package_name()) -> string(). -concat(A, B) -> - concat([A, B]). - --spec concat([package_name()]) -> string(). -concat([H | T]) when is_atom(H) -> - concat([atom_to_list(H) | T]); -concat(["" | T]) -> - concat_1(T); -concat(L) -> - concat_1(L). - -concat_1([H | T]) when is_atom(H) -> - concat_1([atom_to_list(H) | T]); -concat_1([H]) -> - H; -concat_1([H | T]) -> - H ++ "." ++ concat_1(T); -concat_1([]) -> - ""; -concat_1(Name) -> - erlang:error({badarg, Name}). - --spec is_valid(package_name()) -> boolean(). -is_valid(Name) when is_atom(Name) -> - is_valid_1(atom_to_list(Name)); -is_valid([$. | _]) -> - false; -is_valid(Name) -> - is_valid_1(Name). - -is_valid_1([$.]) -> false; -is_valid_1([$., $. | _]) -> false; -is_valid_1([H | T]) when is_integer(H), H >= 0 -> - is_valid_1(T); -is_valid_1([]) -> true; -is_valid_1(_) -> false. - --spec split(package_name()) -> [string()]. -split(Name) when is_atom(Name) -> - split_1(atom_to_list(Name), []); -split(Name) -> - split_1(Name, []). - -split_1([$. | T], Cs) -> - [lists:reverse(Cs) | split_1(T, [])]; -split_1([H | T], Cs) when is_integer(H), H >= 0 -> - split_1(T, [H | Cs]); -split_1([], Cs) -> - [lists:reverse(Cs)]; -split_1(_, _) -> - erlang:error(badarg). - -%% This is equivalent to testing if `split(Name)' yields a list of -%% length larger than one (i.e., if the name can be split into two or -%% more segments), but is cheaper. - --spec is_segmented(package_name()) -> boolean(). -is_segmented(Name) when is_atom(Name) -> - is_segmented_1(atom_to_list(Name)); -is_segmented(Name) -> - is_segmented_1(Name). - -is_segmented_1([$. | _]) -> true; -is_segmented_1([H | T]) when is_integer(H), H >= 0 -> - is_segmented_1(T); -is_segmented_1([]) -> false; -is_segmented_1(_) -> - erlang:error(badarg). - --spec last(package_name()) -> string(). -last(Name) -> - last_1(split(Name)). - -last_1([H]) -> H; -last_1([_ | T]) -> last_1(T). - --spec first(package_name()) -> [string()]. -first(Name) -> - first_1(split(Name)). - -first_1([H | T]) when T =/= [] -> [H | first_1(T)]; -first_1(_) -> []. - --spec strip_last(package_name()) -> string(). -strip_last(Name) -> - concat(first(Name)). - -%% This finds all modules available for a given package, using the -%% current code server search path. (There is no guarantee that the -%% modules are loadable; only that the object files exist.) - --spec find_modules(package_name()) -> [string()]. -find_modules(P) -> - find_modules(P, code:get_path()). - --spec find_modules(package_name(), [string()]) -> [string()]. -find_modules(P, Paths) -> - P1 = filename:join(packages:split(P)), - find_modules(P1, Paths, code:objfile_extension(), sets:new()). - -find_modules(P, [Path | Paths], Ext, S0) -> - case file:list_dir(filename:join(Path, P)) of - {ok, Fs} -> - Fs1 = [F || F <- Fs, filename:extension(F) =:= Ext], - S1 = lists:foldl(fun (F, S) -> - F1 = filename:rootname(F, Ext), - sets:add_element(F1, S) - end, - S0, Fs1), - find_modules(P, Paths, Ext, S1); - _ -> - find_modules(P, Paths, Ext, S0) - end; -find_modules(_P, [], _Ext, S) -> - sets:to_list(S). diff --git a/lib/kernel/src/pg2.erl b/lib/kernel/src/pg2.erl index 0d5838716e..1ff10eb303 100644 --- a/lib/kernel/src/pg2.erl +++ b/lib/kernel/src/pg2.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2011. All Rights Reserved. +%% Copyright Ericsson AB 1997-2012. 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 @@ -159,7 +159,7 @@ get_closest_pid(Name) -> -record(state, {}). --opaque state() :: #state{}. +-type state() :: #state{}. -spec init(Arg :: []) -> {'ok', state()}. diff --git a/lib/kernel/src/ram_file.erl b/lib/kernel/src/ram_file.erl index 48ea871433..ca881ff8a4 100644 --- a/lib/kernel/src/ram_file.erl +++ b/lib/kernel/src/ram_file.erl @@ -29,6 +29,7 @@ %% Specialized file operations -export([get_size/1, get_file/1, set_file/2, get_file_close/1]). -export([compress/1, uncompress/1, uuencode/1, uudecode/1, advise/4]). +-export([allocate/3]). -export([open_mode/1]). %% used by ftp-file @@ -72,6 +73,7 @@ -define(RAM_FILE_UUDECODE, 36). -define(RAM_FILE_SIZE, 37). -define(RAM_FILE_ADVISE, 38). +-define(RAM_FILE_ALLOCATE, 39). %% Open modes for RAM_FILE_OPEN -define(RAM_FILE_MODE_READ, 1). @@ -383,6 +385,11 @@ advise(#file_descriptor{module = ?MODULE, data = Port}, Offset, advise(#file_descriptor{}, _Offset, _Length, _Advise) -> {error, enotsup}. +allocate(#file_descriptor{module = ?MODULE, data = Port}, Offset, Length) -> + call_port(Port, <<?RAM_FILE_ALLOCATE, Offset:64/signed, Length:64/signed>>); +allocate(#file_descriptor{}, _Offset, _Length) -> + {error, enotsup}. + %%%----------------------------------------------------------------- diff --git a/lib/kernel/src/rpc.erl b/lib/kernel/src/rpc.erl index 0b1fc6e939..7c965ca384 100644 --- a/lib/kernel/src/rpc.erl +++ b/lib/kernel/src/rpc.erl @@ -62,6 +62,8 @@ %% Internals -export([proxy_user_flush/0]). +-export_type([key/0]). + %%------------------------------------------------------------------------ -type state() :: gb_tree(). diff --git a/lib/kernel/src/user.erl b/lib/kernel/src/user.erl index 88f32df20b..d6449d9e5e 100644 --- a/lib/kernel/src/user.erl +++ b/lib/kernel/src/user.erl @@ -81,7 +81,7 @@ server(PortName,PortSettings) -> run(P) -> put(read_mode,list), - put(unicode,false), + put(encoding,latin1), case init:get_argument(noshell) of %% non-empty list -> noshell {ok, [_|_]} -> @@ -191,39 +191,27 @@ do_io_request(Req, From, ReplyAs, Port, Q0) -> %% New in R13B %% Encoding option (unicode/latin1) io_request({put_chars,unicode,Chars}, Port, Q) -> % Binary new in R9C - put_chars(wrap_characters_to_binary(Chars,unicode, - case get(unicode) of - true -> unicode; - _ -> latin1 - end), Port, Q); + put_chars(wrap_characters_to_binary(Chars,unicode, get(encoding)), Port, Q); io_request({put_chars,unicode,Mod,Func,Args}, Port, Q) -> Result = case catch apply(Mod,Func,Args) of Data when is_list(Data); is_binary(Data) -> - wrap_characters_to_binary(Data,unicode, - case get(unicode) of - true -> unicode; - _ -> latin1 - end); + wrap_characters_to_binary(Data,unicode,get(encoding)); Undef -> Undef end, put_chars(Result, Port, Q); io_request({put_chars,latin1,Chars}, Port, Q) -> % Binary new in R9C - Data = case get(unicode) of - true -> + Data = case get(encoding) of + unicode -> unicode:characters_to_binary(Chars,latin1,unicode); - false -> + latin1 -> erlang:iolist_to_binary(Chars) end, put_chars(Data, Port, Q); io_request({put_chars,latin1,Mod,Func,Args}, Port, Q) -> Result = case catch apply(Mod,Func,Args) of Data when is_list(Data); is_binary(Data) -> - unicode:characters_to_binary(Data,latin1, - case get(unicode) of - true -> unicode; - _ -> latin1 - end); + unicode:characters_to_binary(Data,latin1,get(encoding)); Undef -> Undef end, @@ -351,9 +339,9 @@ check_valid_opts(_) -> do_setopts(Opts, _Port, Q) -> case proplists:get_value(encoding,Opts) of Valid when Valid =:= unicode; Valid =:= utf8 -> - put(unicode,true); + put(encoding,unicode); latin1 -> - put(unicode,false); + put(encoding,latin1); undefined -> ok end, @@ -370,12 +358,7 @@ do_setopts(Opts, _Port, Q) -> getopts(_Port,Q) -> Bin = {binary, get(read_mode) =:= binary}, - Uni = {encoding, case get(unicode) of - true -> - unicode; - _ -> - latin1 - end}, + Uni = {encoding, get(encoding)}, {ok,[Bin,Uni],Q}. @@ -575,31 +558,32 @@ binrev(L, T) -> %% end %% end %% end. -%% get_chars(Prompt, Module, Function, XtraArg, Port, Queue) +%% get_chars(Prompt, Module, Function, XtraArg, Port, Queue, Encoding) %% Gets characters from the input port until the applied function %% returns {stop,Result,RestBuf}. Does not block output until input -%% has been received. +%% has been received. Encoding is the encoding of the data sent to +%% the client and to Function. %% Returns: %% {Status,Result,NewQueue} %% {exit,Reason} %% Entry function. -get_chars(Prompt, M, F, Xa, Port, Q, Fmt) -> +get_chars(Prompt, M, F, Xa, Port, Q, Enc) -> prompt(Port, Prompt), case {get(eof),queue:is_empty(Q)} of {true,true} -> {ok,eof,Q}; _ -> - get_chars(Prompt, M, F, Xa, Port, Q, start, Fmt) + get_chars(Prompt, M, F, Xa, Port, Q, start, Enc) end. %% First loop. Wait for port data. Respond to output requests. -get_chars(Prompt, M, F, Xa, Port, Q, State, Fmt) -> +get_chars(Prompt, M, F, Xa, Port, Q, State, Enc) -> case queue:is_empty(Q) of true -> receive {Port,{data,Bytes}} -> - get_chars_bytes(State, M, F, Xa, Port, Q, Bytes, Fmt); + get_chars_bytes(State, M, F, Xa, Port, Q, Bytes, Enc); {Port, eof} -> put(eof, true), {ok, eof, []}; @@ -610,41 +594,41 @@ get_chars(Prompt, M, F, Xa, Port, Q, State, Fmt) -> do_io_request(Req, From, ReplyAs, Port, queue:new()), %Keep Q over this call %% No prompt. - get_chars(Prompt, M, F, Xa, Port, Q, State, Fmt); + get_chars(Prompt, M, F, Xa, Port, Q, State, Enc); {io_request,From,ReplyAs,Request} when is_pid(From) -> get_chars_req(Prompt, M, F, Xa, Port, Q, State, - Request, From, ReplyAs, Fmt); + Request, From, ReplyAs, Enc); {'EXIT',From,What} when node(From) =:= node() -> {exit,What} end; false -> - get_chars_apply(State, M, F, Xa, Port, Q, Fmt) + get_chars_apply(State, M, F, Xa, Port, Q, Enc) end. get_chars_req(Prompt, M, F, XtraArg, Port, Q, State, - Req, From, ReplyAs, Fmt) -> + Req, From, ReplyAs, Enc) -> do_io_request(Req, From, ReplyAs, Port, queue:new()), %Keep Q over this call prompt(Port, Prompt), - get_chars(Prompt, M, F, XtraArg, Port, Q, State, Fmt). + get_chars(Prompt, M, F, XtraArg, Port, Q, State, Enc). %% Second loop. Pass data to client as long as it wants more. %% A ^G in data interrupts loop if 'noshell' is not undefined. -get_chars_bytes(State, M, F, Xa, Port, Q, Bytes, Fmt) -> +get_chars_bytes(State, M, F, Xa, Port, Q, Bytes, Enc) -> case get(shell) of noshell -> - get_chars_apply(State, M, F, Xa, Port, queue:snoc(Q, Bytes),Fmt); + get_chars_apply(State, M, F, Xa, Port, queue:snoc(Q, Bytes),Enc); _ -> case contains_ctrl_g_or_ctrl_c(Bytes) of false -> get_chars_apply(State, M, F, Xa, Port, - queue:snoc(Q, Bytes),Fmt); + queue:snoc(Q, Bytes),Enc); _ -> throw(new_shell) end end. -get_chars_apply(State0, M, F, Xa, Port, Q, Fmt) -> - case catch M:F(State0, cast(queue:head(Q),Fmt), Fmt, Xa) of +get_chars_apply(State0, M, F, Xa, Port, Q, Enc) -> + case catch M:F(State0, cast(queue:head(Q),Enc), Enc, Xa) of {stop,Result,<<>>} -> {ok,Result,queue:tail(Q)}; {stop,Result,[]} -> @@ -653,32 +637,32 @@ get_chars_apply(State0, M, F, Xa, Port, Q, Fmt) -> {ok,Result,queue:tail(Q)}; {stop,Result,Buf} -> {ok,Result,queue:cons(Buf, queue:tail(Q))}; - {'EXIT',_} -> + {'EXIT',_Why} -> {error,{error,err_func(M, F, Xa)},queue:new()}; State1 -> - get_chars_more(State1, M, F, Xa, Port, queue:tail(Q), Fmt) + get_chars_more(State1, M, F, Xa, Port, queue:tail(Q), Enc) end. -get_chars_more(State, M, F, Xa, Port, Q, Fmt) -> +get_chars_more(State, M, F, Xa, Port, Q, Enc) -> case queue:is_empty(Q) of true -> case get(eof) of undefined -> receive {Port,{data,Bytes}} -> - get_chars_bytes(State, M, F, Xa, Port, Q, Bytes, Fmt); + get_chars_bytes(State, M, F, Xa, Port, Q, Bytes, Enc); {Port,eof} -> put(eof, true), get_chars_apply(State, M, F, Xa, Port, - queue:snoc(Q, eof), Fmt); + queue:snoc(Q, eof), Enc); {'EXIT',From,What} when node(From) =:= node() -> {exit,What} end; _ -> - get_chars_apply(State, M, F, Xa, Port, queue:snoc(Q, eof), Fmt) + get_chars_apply(State, M, F, Xa, Port, queue:snoc(Q, eof), Enc) end; false -> - get_chars_apply(State, M, F, Xa, Port, Q, Fmt) + get_chars_apply(State, M, F, Xa, Port, Q, Enc) end. @@ -689,11 +673,10 @@ get_chars_more(State, M, F, Xa, Port, Q, Fmt) -> prompt(_Port, '') -> ok; prompt(Port, Prompt) -> - put_port(wrap_characters_to_binary(io_lib:format_prompt(Prompt),unicode, - case get(unicode) of - true -> unicode; - _ -> latin1 - end), Port). + Encoding = get(encoding), + put_port(wrap_characters_to_binary(io_lib:format_prompt(Prompt, Encoding), + unicode, Encoding), + Port). %% Convert error code to make it look as before err_func(io_lib, get_until, {_,F,_}) -> @@ -710,56 +693,65 @@ contains_ctrl_g_or_ctrl_c(BinOrList)-> end. %% Convert a buffer between list and binary -cast(Data, _Format) when is_atom(Data) -> +cast(Data, _Encoding) when is_atom(Data) -> Data; -cast(Data, Format) -> - cast(Data, get(read_mode), Format, get(unicode)). +cast(Data, Encoding) -> + IoEncoding = get(encoding), + cast(Data, get(read_mode), IoEncoding, Encoding). -cast(B, binary, latin1, false) when is_binary(B) -> +cast(B, binary, latin1, latin1) when is_binary(B) -> B; -cast(B, binary, latin1, true) when is_binary(B) -> - unicode:characters_to_binary(B, unicode, latin1); -cast(L, binary, latin1, false) -> - erlang:iolist_to_binary(L); -cast(L, binary, latin1, true) -> - case unicode:characters_to_binary( - erlang:iolist_to_binary(L),unicode,latin1) of % may fail - {error,_,_} -> exit({no_translation, unicode, latin1}); - Else -> Else +cast(L, binary, latin1, latin1) -> + case catch erlang:iolist_to_binary(L) of + Bin when is_binary(Bin) -> Bin; + _ -> exit({no_translation, latin1, latin1}) + end; +cast(Data, binary, unicode, latin1) when is_binary(Data); is_list(Data) -> + case catch unicode:characters_to_binary(Data, unicode, latin1) of + Bin when is_binary(Bin) -> Bin; + _ -> exit({no_translation, unicode, latin1}) + end; +cast(Data, binary, latin1, unicode) when is_binary(Data); is_list(Data) -> + case catch unicode:characters_to_binary(Data, latin1, unicode) of + Bin when is_binary(Bin) -> Bin; + _ -> exit({no_translation, latin1, unicode}) end; -cast(B, binary, unicode, true) when is_binary(B) -> +cast(B, binary, unicode, unicode) when is_binary(B) -> B; -cast(B, binary, unicode, false) when is_binary(B) -> - unicode:characters_to_binary(B,latin1,unicode); -cast(L, binary, unicode, true) -> - % possibly a list containing UTF-8 encoded characters - unicode:characters_to_binary(erlang:iolist_to_binary(L)); -cast(L, binary, unicode, false) -> - unicode:characters_to_binary(L, latin1, unicode); -cast(L, list, latin1, UniTerm) -> - case UniTerm of - true -> % Convert input characters to protocol format (i.e latin1) - case unicode:characters_to_list( - erlang:iolist_to_binary(L),unicode) of % may fail - {error,_,_} -> exit({no_translation, unicode, latin1}); - Else -> [ case X of - High when High > 255 -> - exit({no_translation, unicode, latin1}); - Low -> - Low - end || X <- Else ] - end; - _ -> - binary_to_list(erlang:iolist_to_binary(L)) +cast(L, binary, unicode, unicode) -> + case catch unicode:characters_to_binary(L, unicode) of + Bin when is_binary(Bin) -> Bin; + _ -> exit({no_translation, unicode, unicode}) end; -cast(L, list, unicode, UniTerm) -> - unicode:characters_to_list(erlang:iolist_to_binary(L), - case UniTerm of - true -> unicode; - _ -> latin1 - end); -cast(Other, _, _,_) -> - Other. +cast(B, list, latin1, latin1) when is_binary(B) -> + binary_to_list(B); +cast(L, list, latin1, latin1) -> + case catch erlang:iolist_to_binary(L) of + Bin when is_binary(Bin) -> binary_to_list(Bin); + _ -> exit({no_translation, latin1, latin1}) + end; +cast(Data, list, unicode, latin1) when is_binary(Data); is_list(Data) -> + case catch unicode:characters_to_list(Data, unicode) of + Chars when is_list(Chars) -> + [ case X of + High when High > 255 -> + exit({no_translation, unicode, latin1}); + Low -> + Low + end || X <- Chars ]; + _ -> + exit({no_translation, unicode, latin1}) + end; +cast(Data, list, latin1, unicode) when is_binary(Data); is_list(Data) -> + case catch unicode:characters_to_list(Data, latin1) of + Chars when is_list(Chars) -> Chars; + _ -> exit({no_translation, latin1, unicode}) + end; +cast(Data, list, unicode, unicode) when is_binary(Data); is_list(Data) -> + case catch unicode:characters_to_list(Data, unicode) of + Chars when is_list(Chars) -> Chars; + _ -> exit({no_translation, unicode, unicode}) + end. wrap_characters_to_binary(Chars,unicode,latin1) -> case unicode:characters_to_binary(Chars,unicode,latin1) of diff --git a/lib/kernel/src/wrap_log_reader.erl b/lib/kernel/src/wrap_log_reader.erl index c41e0091e4..689269fc28 100644 --- a/lib/kernel/src/wrap_log_reader.erl +++ b/lib/kernel/src/wrap_log_reader.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1998-2011. All Rights Reserved. +%% Copyright Ericsson AB 1998-2012. 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 @@ -30,6 +30,8 @@ -export([open/1, open/2, chunk/1, chunk/2, close/1]). +-export_type([continuation/0]). + -include("disk_log.hrl"). -record(wrap_reader, |