diff options
Diffstat (limited to 'lib/kernel/src')
-rw-r--r-- | lib/kernel/src/application_controller.erl | 43 | ||||
-rw-r--r-- | lib/kernel/src/auth.erl | 52 | ||||
-rw-r--r-- | lib/kernel/src/code_server.erl | 18 | ||||
-rw-r--r-- | lib/kernel/src/disk_log.hrl | 20 | ||||
-rw-r--r-- | lib/kernel/src/disk_log_1.erl | 16 | ||||
-rw-r--r-- | lib/kernel/src/erl_boot_server.erl | 26 | ||||
-rw-r--r-- | lib/kernel/src/erl_epmd.erl | 26 | ||||
-rw-r--r-- | lib/kernel/src/file.erl | 9 | ||||
-rw-r--r-- | lib/kernel/src/file_server.erl | 33 | ||||
-rw-r--r-- | lib/kernel/src/global.erl | 131 | ||||
-rw-r--r-- | lib/kernel/src/inet_db.erl | 17 | ||||
-rw-r--r-- | lib/kernel/src/inet_gethost_native.erl | 10 | ||||
-rw-r--r-- | lib/kernel/src/kernel_config.erl | 23 | ||||
-rw-r--r-- | lib/kernel/src/os.erl | 59 | ||||
-rw-r--r-- | lib/kernel/src/rpc.erl | 36 | ||||
-rw-r--r-- | lib/kernel/src/standard_error.erl | 16 | ||||
-rw-r--r-- | lib/kernel/src/wrap_log_reader.erl | 12 |
17 files changed, 330 insertions, 217 deletions
diff --git a/lib/kernel/src/application_controller.erl b/lib/kernel/src/application_controller.erl index 7c1f059875..5277472ea6 100644 --- a/lib/kernel/src/application_controller.erl +++ b/lib/kernel/src/application_controller.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1996-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1996-2010. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% -module(application_controller). @@ -128,8 +128,13 @@ %% AppName = atom() %% Application = App | AppName %%----------------------------------------------------------------- + +-type appname() :: atom(). + -record(state, {loading = [], starting = [], start_p_false = [], running = [], control = [], started = [], start_req = [], conf_data}). +-type state() :: #state{}. + %%----------------------------------------------------------------- %% loading = [{AppName, From}] - Load not yet finished %% starting = [{AppName, RestartType, Type, From}] - Start not @@ -604,6 +609,19 @@ check_para([Else | _ParaList], AppName) -> lists:flatten(io_lib:format("~p",[Else]))}. +-type calls() :: 'info' | 'prep_config_change' | 'which_applications' + | {'config_change' | 'control_application' | + 'load_application' | 'start_type' | 'stop_application' | + 'unload_application', term()} + | {'change_application_data', _, _} + | {'permit_application', atom() | {'application',atom(),_},_} + | {'start_application', _, _} + | {'unset_env', _, _} + | {'set_env', _, _, _}. + +-spec handle_call(calls(), {pid(), term()}, state()) -> + {'noreply', state()} | {'reply', term(), state()}. + handle_call({load_application, Application}, From, S) -> case catch do_load_application(Application, S) of {ok, NewS} -> @@ -885,6 +903,9 @@ handle_call(info, _From, S) -> {starting, S#state.starting}], {reply, Reply, S}. +-spec handle_cast({'application_started', appname(), _}, state()) -> + {'noreply', state()} | {'stop', string(), state()}. + handle_cast({application_started, AppName, Res}, S) -> handle_application_started(AppName, Res, S). @@ -977,6 +998,9 @@ handle_application_started(AppName, Res, S) -> {stop, to_string(Reason), S} end. +-spec handle_info(term(), state()) -> + {'noreply', state()} | {'stop', string(), state()}. + handle_info({ac_load_application_reply, AppName, Res}, S) -> case keysearchdelete(AppName, 1, S#state.loading) of {value, {_AppName, From}, Loading} -> @@ -1155,6 +1179,8 @@ handle_info({'EXIT', Pid, Reason}, S) -> handle_info(_, S) -> {noreply, S}. +-spec terminate(term(), state()) -> 'ok'. + terminate(Reason, S) -> case application:get_env(kernel, shutdown_func) of {ok, {M, F}} -> @@ -1170,8 +1196,10 @@ terminate(Reason, S) -> (_) -> ok end, S#state.running), - ets:delete(ac_tab). + true = ets:delete(ac_tab), + ok. +-spec code_change(term(), state(), term()) -> {'ok', state()}. code_change(_OldVsn, State, _Extra) -> {ok, State}. @@ -1937,6 +1965,9 @@ test_make_apps([A|Apps], Res) -> %% Exit reason needs to be a printable string %% (and of length <200, but init now does the chopping). %%----------------------------------------------------------------- + +-spec to_string(term()) -> string(). + to_string(Term) -> case io_lib:printable_list(Term) of true -> diff --git a/lib/kernel/src/auth.erl b/lib/kernel/src/auth.erl index 62c0bef0cc..31ee1d1ef4 100644 --- a/lib/kernel/src/auth.erl +++ b/lib/kernel/src/auth.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1996-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1996-2010. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% -module(auth). @@ -37,10 +37,12 @@ -define(COOKIE_ETS_PROTECTION, protected). +-type cookie() :: atom(). -record(state, { - our_cookie, %% Our own cookie - other_cookies %% The send-cookies of other nodes + our_cookie :: cookie(), %% Our own cookie + other_cookies :: ets:tab() %% The send-cookies of other nodes }). +-type state() :: #state{}. -include("../include/file.hrl"). @@ -61,24 +63,24 @@ is_auth(Node) -> pang -> no end. --spec cookie() -> atom(). +-spec cookie() -> cookie(). cookie() -> get_cookie(). --spec cookie(Cookies :: [atom(),...] | atom()) -> 'true'. +-spec cookie(Cookies :: [cookie(),...] | cookie()) -> 'true'. cookie([Cookie]) -> set_cookie(Cookie); cookie(Cookie) -> set_cookie(Cookie). --spec node_cookie(Cookies :: [atom(),...]) -> 'yes' | 'no'. +-spec node_cookie(Cookies :: [node() | cookie(),...]) -> 'yes' | 'no'. node_cookie([Node, Cookie]) -> node_cookie(Node, Cookie). --spec node_cookie(Node :: node(), Cookie :: atom()) -> 'yes' | 'no'. +-spec node_cookie(Node :: node(), Cookie :: cookie()) -> 'yes' | 'no'. node_cookie(Node, Cookie) -> set_cookie(Node, Cookie), @@ -86,24 +88,24 @@ node_cookie(Node, Cookie) -> %%--"New" interface----------------------------------------------------- --spec get_cookie() -> atom(). +-spec get_cookie() -> 'nocookie' | cookie(). get_cookie() -> get_cookie(node()). --spec get_cookie(Node :: node()) -> atom(). +-spec get_cookie(Node :: node()) -> 'nocookie' | cookie(). get_cookie(_Node) when node() =:= nonode@nohost -> nocookie; get_cookie(Node) -> gen_server:call(auth, {get_cookie, Node}). --spec set_cookie(Cookie :: atom()) -> 'true'. +-spec set_cookie(Cookie :: cookie()) -> 'true'. set_cookie(Cookie) -> set_cookie(node(), Cookie). --spec set_cookie(Node :: node(), Cookie :: atom()) -> 'true'. +-spec set_cookie(Node :: node(), Cookie :: cookie()) -> 'true'. set_cookie(_Node, _Cookie) when node() =:= nonode@nohost -> erlang:error(distribution_not_started); @@ -122,6 +124,8 @@ print(Node,Format,Args) -> %%--gen_server callbacks------------------------------------------------ +-spec init([]) -> {'ok', state()}. + init([]) -> process_flag(trap_exit, true), {ok, init_cookie()}. @@ -130,6 +134,11 @@ init([]) -> %% The net kernel will let all message to the auth server %% through as is +-type calls() :: 'echo' | 'sync_cookie' | {'set_cookie', node(), term()}. + +-spec handle_call(calls(), {pid(), term()}, state()) -> + {'reply', 'hello' | 'true' | 'nocookie' | cookie(), state()}. + handle_call({get_cookie, Node}, {_From,_Tag}, State) when Node =:= node() -> {reply, State#state.our_cookie, State}; handle_call({get_cookie, Node}, {_From,_Tag}, State) -> @@ -164,6 +173,13 @@ handle_call(sync_cookie, _From, State) -> handle_call(echo, _From, O) -> {reply, hello, O}. +%% +%% handle_cast/2 +%% + +-spec handle_cast({'print', string(), [term()]}, state()) -> + {'noreply', state()}. + handle_cast({print,What,Args}, O) -> %% always allow print outs error_logger:error_msg(What,Args), @@ -171,6 +187,8 @@ handle_cast({print,What,Args}, O) -> %% A series of bad messages that may come (from older distribution versions). +-spec handle_info(term(), state()) -> {'noreply', state()}. + handle_info({From,badcookie,net_kernel,{From,spawn,_M,_F,_A,_Gleader}}, O) -> auth:print(node(From) ,"~n** Unauthorized spawn attempt to ~w **~n", [node()]), @@ -218,9 +236,13 @@ handle_info({From,badcookie,Name,Mess}, Opened) -> handle_info(_, O)-> % Ignore anything else especially EXIT signals {noreply, O}. +-spec code_change(term(), state(), term()) -> {'ok', state()}. + code_change(_OldVsn, State, _Extra) -> {ok, State}. +-spec terminate(term(), state()) -> 'ok'. + terminate(_Reason, _State) -> ok. diff --git a/lib/kernel/src/code_server.erl b/lib/kernel/src/code_server.erl index 7aeddb73d1..2bc93b8238 100644 --- a/lib/kernel/src/code_server.erl +++ b/lib/kernel/src/code_server.erl @@ -32,14 +32,15 @@ -import(lists, [foreach/2]). --record(state,{supervisor, - root, - path, - moddb, - namedb, - cache = no_cache, - mode=interactive, - on_load = []}). +-record(state, {supervisor, + root, + path, + moddb, + namedb, + cache = no_cache, + mode = interactive, + on_load = []}). +-type state() :: #state{}. start_link(Args) -> Ref = make_ref(), @@ -221,6 +222,7 @@ system_terminate(_Reason, _Parent, _Debug, _State) -> % error_msg("~p terminating: ~p~n ",[?MODULE,Reason]), exit(shutdown). +-spec system_code_change(state(), module(), term(), term()) -> {'ok', state()}. system_code_change(State, _Module, _OldVsn, _Extra) -> {ok, State}. diff --git a/lib/kernel/src/disk_log.hrl b/lib/kernel/src/disk_log.hrl index b0849145ca..9a94d4d3b9 100644 --- a/lib/kernel/src/disk_log.hrl +++ b/lib/kernel/src/disk_log.hrl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1997-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1997-2010. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% @@ -44,17 +44,11 @@ -define(OPENED, <<6,7,8,9>>). -define(CLOSED, <<99,88,77,11>>). -%% Needed for the definition of fd() +%% Needed for the definition of #file_info{} %% Must use include_lib() so that we always can be sure to find %% file.hrl. A relative path will not work in an installed system. -include_lib("kernel/include/file.hrl"). -%% Ugly workaround. If we are building the bootstrap compiler, -%% file.hrl does not define the fd() type. --ifndef(FILE_HRL_). --type fd() :: pid() | #file_descriptor{}. --endif. - %%------------------------------------------------------------------------ %% Types -- alphabetically %%------------------------------------------------------------------------ @@ -94,7 +88,7 @@ options = [] :: dlog_options()}). -record(cache, %% Cache for logged terms (per file descriptor). - {fd :: fd(), %% File descriptor. + {fd :: file:fd(), %% File descriptor. sz = 0 :: non_neg_integer(), %% Number of bytes in the cache. c = [] :: iodata()} %% The cache. ). diff --git a/lib/kernel/src/disk_log_1.erl b/lib/kernel/src/disk_log_1.erl index 7103417149..8ccdb88d12 100644 --- a/lib/kernel/src/disk_log_1.erl +++ b/lib/kernel/src/disk_log_1.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1997-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1997-2010. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% -module(disk_log_1). @@ -1529,7 +1529,7 @@ write_cache(Fd, FileName, C) -> Error -> {catch file_error(FileName, Error), #cache{fd = Fd}} end. --spec write_cache_close(fd(), file:filename(), iodata()) -> #cache{}. % | throw(Error) +-spec write_cache_close(file:fd(), file:filename(), iodata()) -> #cache{}. % | throw(Error) write_cache_close(Fd, _FileName, []) -> #cache{fd = Fd}; @@ -1539,12 +1539,12 @@ write_cache_close(Fd, FileName, C) -> Error -> file_error_close(Fd, FileName, Error) end. --spec file_error(file:filename(), {'error', atom()}) -> no_return(). +-spec file_error(file:filename(), {'error', file:posix()}) -> no_return(). file_error(FileName, {error, Error}) -> throw({error, {file_error, FileName, Error}}). --spec file_error_close(fd(), file:filename(), {'error', atom()}) -> no_return(). +-spec file_error_close(file:fd(), file:filename(), {'error', file:posix()}) -> no_return(). file_error_close(Fd, FileName, {error, Error}) -> file:close(Fd), diff --git a/lib/kernel/src/erl_boot_server.erl b/lib/kernel/src/erl_boot_server.erl index 702b2feac9..c5a4305731 100644 --- a/lib/kernel/src/erl_boot_server.erl +++ b/lib/kernel/src/erl_boot_server.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1996-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1996-2010. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% %% A simple boot_server at a CP. @@ -53,6 +53,7 @@ bootp :: pid(), %% boot process prim_state %% state for efile code loader }). +-type state() :: #state{}. -define(single_addr_mask, {255, 255, 255, 255}). @@ -165,6 +166,8 @@ member_address(_, []) -> %% call-back functions. %% ------------------------------------------------------------ +-spec init([atom()]) -> {'ok', state()}. + init(Slaves) -> {ok, U} = gen_udp:open(?EBOOT_PORT, []), {ok, L} = gen_tcp:listen(0, [binary,{packet,4}]), @@ -186,6 +189,9 @@ init(Slaves) -> bootp = Pid }}. +-spec handle_call('which' | {'add',atom()} | {'delete',atom()}, _, state()) -> + {'reply', 'ok' | [atom()], state()}. + handle_call({add,Address}, _, S0) -> Slaves = ordsets:add_element(Address, S0#state.slaves), S0#state.bootp ! {slaves, Slaves}, @@ -197,9 +203,13 @@ handle_call({delete,Address}, _, S0) -> handle_call(which, _, S0) -> {reply, ordsets:to_list(S0#state.slaves), S0}. +-spec handle_cast(term(), [atom()]) -> {'noreply', [atom()]}. + handle_cast(_, Slaves) -> {noreply, Slaves}. +-spec handle_info(term(), state()) -> {'noreply', state()}. + handle_info({udp, U, IP, Port, Data}, S0) -> Token = ?EBOOT_REQUEST ++ S0#state.version, Valid = member_address(IP, ordsets:to_list(S0#state.slaves)), @@ -230,9 +240,13 @@ handle_info({udp, U, IP, Port, Data}, S0) -> handle_info(_Info, S0) -> {noreply,S0}. +-spec terminate(term(), state()) -> 'ok'. + terminate(_Reason, _S0) -> ok. +-spec code_change(term(), state(), term()) -> {'ok', state()}. + code_change(_Vsn, State, _Extra) -> {ok, State}. @@ -242,6 +256,8 @@ code_change(_Vsn, State, _Extra) -> %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec boot_init(reference()) -> no_return(). + boot_init(Tag) -> receive {Tag, Listen} -> diff --git a/lib/kernel/src/erl_epmd.erl b/lib/kernel/src/erl_epmd.erl index e4b371836b..c4ff4c7281 100644 --- a/lib/kernel/src/erl_epmd.erl +++ b/lib/kernel/src/erl_epmd.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1998-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1998-2010. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% -module(erl_epmd). @@ -40,6 +40,7 @@ -import(lists, [reverse/1]). -record(state, {socket, port_no = -1, name = ""}). +-type state() :: #state{}. -include("inet_int.hrl"). -include("erl_epmd.hrl"). @@ -111,11 +112,18 @@ register_node(Name, PortNo) -> %%% Callback functions from gen_server %%%---------------------------------------------------------------------- +-spec init(_) -> {'ok', state()}. + init(_) -> {ok, #state{socket = -1}}. %%---------------------------------------------------------------------- +-type calls() :: 'client_info_req' | 'stop' | {'register', term(), term()}. + +-spec handle_call(calls(), term(), state()) -> + {'reply', term(), state()} | {'stop', 'shutdown', 'ok', state()}. + handle_call({register, Name, PortNo}, _From, State) -> case State#state.socket of P when P < 0 -> @@ -141,11 +149,15 @@ handle_call(stop, _From, State) -> %%---------------------------------------------------------------------- +-spec handle_cast(term(), state()) -> {'noreply', state()}. + handle_cast(_, State) -> {noreply, State}. %%---------------------------------------------------------------------- +-spec handle_info(term(), state()) -> {'noreply', state()}. + handle_info({tcp_closed, Socket}, State) when State#state.socket =:= Socket -> {noreply, State#state{socket = -1}}; handle_info(_, State) -> @@ -153,6 +165,8 @@ handle_info(_, State) -> %%---------------------------------------------------------------------- +-spec terminate(term(), state()) -> 'ok'. + terminate(_, #state{socket = Socket}) when Socket > 0 -> close(Socket), ok; @@ -161,6 +175,8 @@ terminate(_, _) -> %%---------------------------------------------------------------------- +-spec code_change(term(), state(), term()) -> {'ok', state()}. + code_change(_OldVsn, State, _Extra) -> {ok, State}. diff --git a/lib/kernel/src/file.erl b/lib/kernel/src/file.erl index a42771dfb6..46ffa9d708 100644 --- a/lib/kernel/src/file.erl +++ b/lib/kernel/src/file.erl @@ -74,15 +74,22 @@ %% data types -type filename() :: string(). -type file_info() :: #file_info{}. --type io_device() :: pid() | #file_descriptor{}. +-type fd() :: #file_descriptor{}. +-type io_device() :: pid() | fd(). -type location() :: integer() | {'bof', integer()} | {'cur', integer()} | {'eof', integer()} | 'bof' | 'cur' | 'eof'. -type mode() :: 'read' | 'write' | 'append' | 'raw' | 'binary' | {'delayed_write', non_neg_integer(), non_neg_integer()} | 'delayed_write' | {'read_ahead', pos_integer()} | 'read_ahead' | 'compressed'. +-type name() :: string() | atom() | [name()]. +-type posix() :: atom(). -type bindings() :: any(). +-type date() :: {pos_integer(), pos_integer(), pos_integer()}. +-type time() :: {non_neg_integer(), non_neg_integer(), non_neg_integer()}. +-type date_time() :: {date(), time()}. + %%%----------------------------------------------------------------- %%% General functions diff --git a/lib/kernel/src/file_server.erl b/lib/kernel/src/file_server.erl index 74f2fb94a9..64c61ba3ac 100644 --- a/lib/kernel/src/file_server.erl +++ b/lib/kernel/src/file_server.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2000-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 2000-2010. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% @@ -62,6 +62,8 @@ stop() -> %%% Callback functions from gen_server %%%---------------------------------------------------------------------- +-type state() :: port(). % Internal type + %%---------------------------------------------------------------------- %% Func: init/1 %% Returns: {ok, State} | @@ -69,6 +71,9 @@ stop() -> %% ignore | %% {stop, Reason} %%---------------------------------------------------------------------- + +-spec init([]) -> {'ok', state()} | {'stop', term()}. + init([]) -> process_flag(trap_exit, true), case ?PRIM_FILE:start() of @@ -88,6 +93,12 @@ init([]) -> %% {stop, Reason, Reply, State} | (terminate/2 is called) %% {stop, Reason, State} (terminate/2 is called) %%---------------------------------------------------------------------- + +-spec handle_call(term(), term(), state()) -> + {'noreply', state()} | + {'reply', 'eof' | 'ok' | {'error', term()} | {'ok', term()}, state()} | + {'stop', 'normal', 'stopped', state()}. + handle_call({open, Name, ModeList}, {Pid, _Tag} = _From, Handle) when is_list(ModeList) -> Child = ?FILE_IO_SERVER:start_link(Pid, Name, ModeList), @@ -190,6 +201,9 @@ handle_call(Request, From, Handle) -> %% {noreply, State, Timeout} | %% {stop, Reason, State} (terminate/2 is called) %%---------------------------------------------------------------------- + +-spec handle_cast(term(), state()) -> {'noreply', state()}. + handle_cast(Msg, State) -> error_logger:error_msg("handle_cast(~p, _)", [Msg]), {noreply, State}. @@ -201,6 +215,9 @@ handle_cast(Msg, State) -> %% {stop, Reason, State} (terminate/2 is called) %%---------------------------------------------------------------------- +-spec handle_info(term(), state()) -> + {'noreply', state()} | {'stop', 'normal', state()}. + handle_info({'EXIT', Pid, _Reason}, Handle) when is_pid(Pid) -> ets:delete(?FILE_IO_SERVER_TABLE, Pid), {noreply, Handle}; @@ -219,6 +236,9 @@ handle_info(Info, State) -> %% Purpose: Shutdown the server %% Returns: any (ignored by gen_server) %%---------------------------------------------------------------------- + +-spec terminate(term(), state()) -> 'ok'. + terminate(_Reason, Handle) -> ?PRIM_FILE:stop(Handle). @@ -227,6 +247,9 @@ terminate(_Reason, Handle) -> %% Purpose: Convert process state when code is changed %% Returns: {ok, NewState} %%---------------------------------------------------------------------- + +-spec code_change(term(), state(), term()) -> {'ok', state()}. + code_change(_OldVsn, State, _Extra) -> {ok, State}. diff --git a/lib/kernel/src/global.erl b/lib/kernel/src/global.erl index cc0402da73..081e7e2f93 100644 --- a/lib/kernel/src/global.erl +++ b/lib/kernel/src/global.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1996-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1996-2010. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% -module(global). @@ -112,7 +112,7 @@ resolvers = [], syncers = [] :: [pid()], node_name = node() :: node(), - the_locker, the_deleter, the_registrar, trace, + the_locker, the_registrar, trace, global_lock_down = false }). @@ -153,6 +153,8 @@ %%% It can be removed later as can the deleter process. %%% An extra process calling erlang:monitor() is sometimes created. %%% The new_nodes messages has been augmented with the global lock id. +%%% +%%% R14A (OTP-8527): The deleter process has been removed. start() -> gen_server:start({local, global_name_server}, ?MODULE, [], []). @@ -418,7 +420,6 @@ init([]) -> S = #state{the_locker = start_the_locker(DoTrace), trace = T0, - the_deleter = start_the_deleter(self()), the_registrar = start_the_registrar()}, S1 = trace_message(S, {init, node()}, []), @@ -763,13 +764,16 @@ handle_cast({in_sync, Node, _IsKnown}, S) -> %% Called when Pid on other node crashed handle_cast({async_del_name, _Name, _Pid}, S) -> - %% Sent from the_deleter at some node in the partition but node(). + %% Sent from the_deleter at some node in the partition but node() (-R13B) %% The DOWN message deletes the name. + %% R14A nodes and later do not send async_del_name messages. {noreply, S}; handle_cast({async_del_lock, _ResourceId, _Pid}, S) -> - %% Sent from global_name_server at some node in the partition but node(). + %% Sent from global_name_server at some node in the partition but + %% node(). (-R13B) %% The DOWN message deletes the lock. + %% R14A nodes and later do not send async_del_lock messages. {noreply, S}; handle_cast(Request, S) -> @@ -778,8 +782,6 @@ handle_cast(Request, S) -> "handle_cast(~p, _)\n", [Request]), {noreply, S}. -handle_info({'EXIT', Deleter, _Reason}=Exit, #state{the_deleter=Deleter}=S) -> - {stop, {deleter_died,Exit}, S#state{the_deleter=undefined}}; handle_info({'EXIT', Locker, _Reason}=Exit, #state{the_locker=Locker}=S) -> {stop, {locker_died,Exit}, S#state{the_locker=undefined}}; handle_info({'EXIT', Registrar, _}=Exit, #state{the_registrar=Registrar}=S) -> @@ -1348,30 +1350,13 @@ lock_still_set(PidOrNode, ExtraInfo, S) -> [{?GLOBAL_RID, _LockReqId, PidRefs}] when is_pid(PidOrNode) -> %% Name registration. lists:keymember(PidOrNode, 1, PidRefs); - [{?GLOBAL_RID, LockReqId, PidRefs}] when is_atom(PidOrNode) -> - case extra_info(lock, ExtraInfo) of - {?GLOBAL_RID, LockId} -> % R11B-4 or later - LockReqId =:= LockId; - undefined -> - lock_still_set_old(PidOrNode, LockReqId, PidRefs) - end; + [{?GLOBAL_RID, LockReqId, _PidRefs}] when is_atom(PidOrNode) -> + {?GLOBAL_RID, LockId} = extra_info(lock, ExtraInfo), + LockReqId =:= LockId; [] -> - %% If the global lock was not removed by a DOWN message - %% then we have a node that do not monitor locking pids - %% (pre R11B-3), or an R11B-3 node (which does not ensure - %% that {new_nodes, ...} arrives before {del_lock, ...}). not S#state.global_lock_down end. -%%% The following is probably overkill. It is possible that this node -%%% has been locked again, but it is a rare occasion. -lock_still_set_old(_Node, ReqId, _PidRefs) when is_pid(ReqId) -> - %% Cannot do better than return true. - true; -lock_still_set_old(Node, ReqId, PidRefs) when is_list(ReqId) -> - %% Connection, version > 4, but before R11B-4. - [P || {P, _RPid, _Ref} <- PidRefs, node(P) =:= Node] =/= []. - extra_info(Tag, ExtraInfo) -> %% ExtraInfo used to be a list of nodes (vsn 2). case catch lists:keyfind(Tag, 1, ExtraInfo) of @@ -1382,36 +1367,18 @@ extra_info(Tag, ExtraInfo) -> end. del_name(Ref, S) -> - NameL = [{Name, Pid} || + NameL = [Name || {_, Name} <- ets:lookup(global_pid_names, Ref), - {_, Pid, _Method, _RPid, Ref1} <- + {_, _Pid, _Method, _RPid, Ref1} <- ets:lookup(global_names, Name), Ref1 =:= Ref], - ?trace({async_del_name, self(), NameL, Ref}), case NameL of - [{Name, Pid}] -> - _ = del_names(Name, Pid, S), + [Name] -> delete_global_name2(Name, S); [] -> S end. -%% Send {async_del_name, ...} to old nodes (pre R11B-3). -del_names(Name, Pid, S) -> - Send = case ets:lookup(global_names_ext, Name) of - [{Name, Pid, RegNode}] -> - RegNode =:= node(); - [] -> - node(Pid) =:= node() - end, - if - Send -> - ?trace({del_names, {pid,Pid}, {name,Name}}), - S#state.the_deleter ! {delete_name, self(), Name, Pid}; - true -> - ok - end. - %% Keeps the entry in global_names for whereis_name/1. delete_global_name_keep_pid(Name, S) -> case ets:lookup(global_names, Name) of @@ -1986,7 +1953,6 @@ pid_is_locking(Pid, PidRefs) -> delete_lock(Ref, S0) -> Locks = pid_locks(Ref), - del_locks(Locks, Ref, S0#state.known), F = fun({ResourceId, LockRequesterId, PidRefs}, S) -> {Pid, _RPid, Ref} = lists:keyfind(Ref, 3, PidRefs), remove_lock(ResourceId, LockRequesterId, Pid, PidRefs, true,S) @@ -2003,20 +1969,6 @@ pid_locks(Ref) -> rpid_is_locking(Ref, PidRefs) -> lists:keyfind(Ref, 3, PidRefs) =/= false. -%% Send {async_del_lock, ...} to old nodes (pre R11B-3). -del_locks([{ResourceId, _LockReqId, PidRefs} | Tail], Ref, KnownNodes) -> - {Pid, _RPid, Ref} = lists:keyfind(Ref, 3, PidRefs), - case node(Pid) =:= node() of - true -> - gen_server:abcast(KnownNodes, global_name_server, - {async_del_lock, ResourceId, Pid}); - false -> - ok - end, - del_locks(Tail, Ref, KnownNodes); -del_locks([], _Ref, _KnownNodes) -> - ok. - handle_nodedown(Node, S) -> %% DOWN signals from monitors have removed locks and registered names. #state{known = Known, synced = Syncs} = S, @@ -2147,51 +2099,6 @@ get_own_nodes() -> OkTup end. -%%----------------------------------------------------------------- -%% The deleter process is a satellite process to global_name_server -%% that does background batch deleting of names when a process -%% that had globally registered names dies. It is started by and -%% linked to global_name_server. -%%----------------------------------------------------------------- - -start_the_deleter(Global) -> - spawn_link(fun() -> loop_the_deleter(Global) end). - -loop_the_deleter(Global) -> - Deletions = collect_deletions(Global, []), - ?trace({loop_the_deleter, self(), {deletions,Deletions}, - {names,get_names()}}), - %% trans_all_known is called rather than trans/3 with nodes() as - %% third argument. The reason is that known gets updated by - %% new_nodes when the lock is still set. nodes() on the other hand - %% could be updated later (if in_sync is received after the lock - %% is gone). It is not likely that in_sync would be received after - %% the lock has been taken here, but using trans_all_known makes it - %% even less likely. - trans_all_known( - fun(Known) -> - lists:map( - fun({Name,Pid}) -> - gen_server:abcast(Known, global_name_server, - {async_del_name, Name, Pid}) - end, Deletions) - end), - loop_the_deleter(Global). - -collect_deletions(Global, Deletions) -> - receive - {delete_name, Global, Name, Pid} -> - collect_deletions(Global, [{Name,Pid} | Deletions]); - Other -> - unexpected_message(Other, deleter), - collect_deletions(Global, Deletions) - after case Deletions of - [] -> infinity; - _ -> 0 - end -> - lists:reverse(Deletions) - end. - %% The registrar is a helper process that registers and unregisters %% names. Since it never dies it assures that names are registered and %% unregistered on all known nodes. It is started by and linked to diff --git a/lib/kernel/src/inet_db.erl b/lib/kernel/src/inet_db.erl index a05b380855..ec95620cc0 100644 --- a/lib/kernel/src/inet_db.erl +++ b/lib/kernel/src/inet_db.erl @@ -88,6 +88,7 @@ hosts_file_byaddr, %% hosts table from system file cache_timer %% timer reference for refresh }). +-type state() :: #state{}. -include("inet.hrl"). -include("inet_int.hrl"). @@ -844,6 +845,9 @@ lookup_socket(Socket) when is_port(Socket) -> %% node_auth Ls - Default authenication %% node_crypt Ls - Default encryption %% + +-spec init([]) -> {'ok', state()}. + init([]) -> process_flag(trap_exit, true), Db = ets:new(inet_db, [public, named_table]), @@ -897,6 +901,10 @@ reset_db(Db) -> %% {stop, Reason, Reply, State} | (terminate/2 is called) %% {stop, Reason, Reply, State} (terminate/2 is called) %%---------------------------------------------------------------------- + +-spec handle_call(term(), {pid(), term()}, state()) -> + {'reply', term(), state()} | {'stop', 'normal', 'ok', state()}. + handle_call(Request, From, #state{db=Db}=State) -> case Request of {load_hosts_file,IPNmAs} when is_list(IPNmAs) -> @@ -1145,6 +1153,9 @@ handle_call(Request, From, #state{db=Db}=State) -> %% {noreply, State, Timeout} | %% {stop, Reason, State} (terminate/2 is called) %%---------------------------------------------------------------------- + +-spec handle_cast(term(), state()) -> {'noreply', state()}. + handle_cast(_Msg, State) -> {noreply, State}. @@ -1154,6 +1165,9 @@ handle_cast(_Msg, State) -> %% {noreply, State, Timeout} | %% {stop, Reason, State} (terminate/2 is called) %%---------------------------------------------------------------------- + +-spec handle_info(term(), state()) -> {'noreply', state()}. + handle_info(refresh_timeout, State) -> do_refresh_cache(State#state.cache), {noreply, State#state{cache_timer = init_timer()}}; @@ -1166,6 +1180,9 @@ handle_info(_Info, State) -> %% Purpose: Shutdown the server %% Returns: any (ignored by gen_server) %%---------------------------------------------------------------------- + +-spec terminate(term(), state()) -> 'ok'. + terminate(_Reason, State) -> stop_timer(State#state.cache_timer), ok. diff --git a/lib/kernel/src/inet_gethost_native.erl b/lib/kernel/src/inet_gethost_native.erl index fabe9bf8b3..b7b3007b99 100644 --- a/lib/kernel/src/inet_gethost_native.erl +++ b/lib/kernel/src/inet_gethost_native.erl @@ -106,8 +106,11 @@ pool_size = 4, % Number of C processes in pool. statistics % Statistics record (records error causes). }). +-type state() :: #state{}. %% The supervisor bridge code +-spec init([]) -> {'ok', pid(), pid()} | {'error', term()}. + init([]) -> % Called by supervisor_bridge:start_link Ref = make_ref(), SaveTE = process_flag(trap_exit,true), @@ -154,8 +157,10 @@ run_once() -> Pid ! {R,{error,timeout}} end. -terminate(_Reason,Pid) -> - (catch exit(Pid,kill)), +-spec terminate(term(), pid()) -> 'ok'. + +terminate(_Reason, Pid) -> + (catch exit(Pid, kill)), ok. %%----------------------------------------------------------------------- @@ -431,6 +436,7 @@ system_continue(_Parent, _, State) -> system_terminate(Reason, _Parent, _, _State) -> exit(Reason). +-spec system_code_change(state(), module(), term(), term()) -> {'ok', state()}. system_code_change(State, _Module, _OldVsn, _Extra) -> {ok, State}. %% Nothing to do in this version. diff --git a/lib/kernel/src/kernel_config.erl b/lib/kernel/src/kernel_config.erl index e5e9a0498d..cdad354876 100644 --- a/lib/kernel/src/kernel_config.erl +++ b/lib/kernel/src/kernel_config.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1996-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1996-2010. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% -module(kernel_config). @@ -40,6 +40,9 @@ start_link() -> gen_server:start_link(kernel_config, [], []). %%----------------------------------------------------------------- %% Callback functions from gen_server %%----------------------------------------------------------------- + +-spec init([]) -> {'ok', []} | {'stop', term()}. + init([]) -> process_flag(trap_exit, true), case sync_nodes() of @@ -59,18 +62,28 @@ init([]) -> {stop, Error} end. +-spec handle_info(term(), State) -> {'noreply', State}. + handle_info(_, State) -> {noreply, State}. +-spec terminate(term(), term()) -> 'ok'. + terminate(_Reason, _State) -> ok. +-spec handle_call(term(), term(), State) -> {'reply', 'ok', State}. + handle_call('__not_used', _From, State) -> {reply, ok, State}. +-spec handle_cast(term(), State) -> {'noreply', State}. + handle_cast('__not_used', State) -> {noreply, State}. +-spec code_change(term(), State, term()) -> {'ok', State}. + code_change(_OldVsn, State, _Extra) -> {ok, State}. diff --git a/lib/kernel/src/os.erl b/lib/kernel/src/os.erl index 196e6cdeb2..d0b498edc9 100644 --- a/lib/kernel/src/os.erl +++ b/lib/kernel/src/os.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1997-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1997-2010. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% -module(os). @@ -169,6 +169,7 @@ unix_cmd(Cmd) -> %% $1 parameter for easy identification of the resident shell. %% -define(SHELL, "/bin/sh -s unix:cmd 2>&1"). +-define(PORT_CREATOR_NAME, os_cmd_port_creator). %% %% Serializing open_port through a process to avoid smp lock contention @@ -176,18 +177,37 @@ unix_cmd(Cmd) -> %% -spec start_port() -> port(). start_port() -> - {Ref,Client} = {make_ref(),self()}, - try (os_cmd_port_creator ! {Ref,Client}) - catch - error:_ -> spawn(fun() -> start_port_srv({Ref,Client}) end) - end, + Ref = make_ref(), + Request = {Ref,self()}, + {Pid, Mon} = case whereis(?PORT_CREATOR_NAME) of + undefined -> + spawn_monitor(fun() -> + start_port_srv(Request) + end); + P -> + P ! Request, + M = erlang:monitor(process, P), + {P, M} + end, receive - {Ref,Port} when is_port(Port) -> Port; - {Ref,Error} -> exit(Error) + {Ref, Port} when is_port(Port) -> + erlang:demonitor(Mon, [flush]), + Port; + {Ref, Error} -> + erlang:demonitor(Mon, [flush]), + exit(Error); + {'DOWN', Mon, process, Pid, _Reason} -> + start_port() end. start_port_srv(Request) -> - StayAlive = try register(os_cmd_port_creator, self()) + %% We don't want a group leader of some random application. Use + %% kernel_sup's group leader. + {group_leader, GL} = process_info(whereis(kernel_sup), + group_leader), + true = group_leader(GL, self()), + process_flag(trap_exit, true), + StayAlive = try register(?PORT_CREATOR_NAME, self()) catch error:_ -> false end, @@ -196,7 +216,7 @@ start_port_srv(Request) -> start_port_srv_loop({Ref,Client}, StayAlive) -> Reply = try open_port({spawn, ?SHELL},[stream]) of Port when is_port(Port) -> - port_connect(Port, Client), + (catch port_connect(Port, Client)), unlink(Port), Port catch @@ -205,10 +225,19 @@ start_port_srv_loop({Ref,Client}, StayAlive) -> end, Client ! {Ref,Reply}, case StayAlive of - true -> start_port_srv_loop(receive Msg -> Msg end, true); + true -> start_port_srv_loop(get_open_port_request(), true); false -> exiting end. +get_open_port_request() -> + receive + {Ref, Client} = Request when is_reference(Ref), + is_pid(Client) -> + Request; + _Junk -> + get_open_port_request() + end. + %% %% unix_get_data(Port) -> Result %% diff --git a/lib/kernel/src/rpc.erl b/lib/kernel/src/rpc.erl index d69f2a12ad..43a987f313 100644 --- a/lib/kernel/src/rpc.erl +++ b/lib/kernel/src/rpc.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1996-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1996-2010. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% -module(rpc). @@ -64,25 +64,41 @@ %%------------------------------------------------------------------------ +-type state() :: gb_tree(). + +%%------------------------------------------------------------------------ + %% Remote execution and broadcasting facility +-spec start() -> {'ok', pid()} | 'ignore' | {'error', term()}. + start() -> gen_server:start({local,?NAME},?MODULE,[],[]). +-spec start_link() -> {'ok', pid()} | 'ignore' | {'error', term()}. + start_link() -> gen_server:start_link({local,?NAME},?MODULE,[],[]). +-spec stop() -> term(). + stop() -> stop(?NAME). stop(Rpc) -> gen_server:call(Rpc, stop, infinity). --spec init([]) -> {'ok', gb_tree()}. +-spec init([]) -> {'ok', state()}. + init([]) -> process_flag(trap_exit, true), {ok, gb_trees:empty()}. +-spec handle_call(term(), term(), state()) -> + {'noreply', state()} | + {'reply', term(), state()} | + {'stop', 'normal', 'stopped', state()}. + handle_call({call, Mod, Fun, Args, Gleader}, To, S) -> handle_call_call(Mod, Fun, Args, Gleader, To, S); handle_call({block_call, Mod, Fun, Args, Gleader}, _To, S) -> @@ -102,6 +118,7 @@ handle_call(stop, _To, S) -> handle_call(_, _To, S) -> {noreply, S}. % Ignore ! +-spec handle_cast(term(), state()) -> {'noreply', state()}. handle_cast({cast, Mod, Fun, Args, Gleader}, S) -> spawn( @@ -113,6 +130,7 @@ handle_cast({cast, Mod, Fun, Args, Gleader}, S) -> handle_cast(_, S) -> {noreply, S}. % Ignore ! +-spec handle_info(term(), state()) -> {'noreply', state()}. handle_info({'DOWN', _, process, Caller, Reason}, S) -> case gb_trees:lookup(Caller, S) of @@ -160,9 +178,13 @@ handle_info({From, {call,Mod,Fun,Args,Gleader}}, S) -> handle_info(_, S) -> {noreply,S}. +-spec terminate(term(), state()) -> 'ok'. + terminate(_, _S) -> ok. +-spec code_change(term(), state(), term()) -> {'ok', state()}. + code_change(_, S, _) -> {ok, S}. @@ -226,6 +248,8 @@ proxy_user_loop() -> undefined -> proxy_user_loop() end. +-spec proxy_user_flush() -> no_return(). + proxy_user_flush() -> %% Forward all received messages to 'user' receive Msg -> diff --git a/lib/kernel/src/standard_error.erl b/lib/kernel/src/standard_error.erl index 73901d9896..98a44d1ee9 100644 --- a/lib/kernel/src/standard_error.erl +++ b/lib/kernel/src/standard_error.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 2009-2010. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% -module(standard_error). @@ -33,13 +33,19 @@ %% %% The basic server and start-up. %% +-spec start_link() -> 'ignore' | {'error',term()} | {'ok',pid()}. + start_link() -> supervisor_bridge:start_link({local, ?PROCNAME_SUP}, ?MODULE, []). +-spec terminate(term(), pid()) -> 'ok'. + terminate(_Reason,Pid) -> (catch exit(Pid,kill)), ok. +-spec init([]) -> {'error','no_stderror'} | {'ok',pid(),pid()}. + init([]) -> case (catch start_port([out,binary])) of Pid when is_pid(Pid) -> diff --git a/lib/kernel/src/wrap_log_reader.erl b/lib/kernel/src/wrap_log_reader.erl index 5030d3aed5..fabaa07752 100644 --- a/lib/kernel/src/wrap_log_reader.erl +++ b/lib/kernel/src/wrap_log_reader.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1998-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1998-2010. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% @@ -37,7 +37,7 @@ cont :: dlog_cont(), % disk_log's continuation record file :: file:filename(), % file name without extension file_no :: non_neg_integer(), % current file number - mod_time :: date_time(), % modification time of current file + mod_time :: file:date_time(), % modification time of current file first_no :: non_neg_integer() | 'one' % first read file number }). |