diff options
author | Lukas Larsson <[email protected]> | 2011-05-18 16:21:34 +0200 |
---|---|---|
committer | Lukas Larsson <[email protected]> | 2011-05-18 16:21:34 +0200 |
commit | 15426ac367eed736c165a5bdbb1c051a87944f68 (patch) | |
tree | fcabce7847168a8416600fe35f94a411a5f73d6e /lib/kernel/src | |
parent | 4cd0717b717803ce8f03a12de4bf89f452ed1df7 (diff) | |
parent | f44bbb331fb517e989d4d906b7f63ec110bbbc18 (diff) | |
download | otp-15426ac367eed736c165a5bdbb1c051a87944f68.tar.gz otp-15426ac367eed736c165a5bdbb1c051a87944f68.tar.bz2 otp-15426ac367eed736c165a5bdbb1c051a87944f68.zip |
Merge branch 'dev' of super:otp into dev
* 'dev' of super:otp: (166 commits)
Corrected documentation error and added examples to Users Guide
In TLS 1.1, failure to properly close a connection no longer requires that a session not be resumed. This is a change from TLS 1.0 to conform with widespread implementation practice. Erlang ssl will now in TLS 1.0 conform to the widespread implementation practice instead of the specification to avoid performance issues.
Add escript to bootstrap/bin
Remove unused variable warning in inet_res
Remove unused variable in epmd_port
Remove compiler warnings in inet_drv
Add SASL test suite
Allow same module name in multiple applications if explicitely excluded
Fix bugs concerning the option report_missing_types
Fix default encoding in SAX parser.
re: remove gratuitous "it " in manpage
Spelling in (backward *compatibility*) comment.
Improve erl_docgen's support for Dialyzer specs and types
dialyzer warning on mnesia_tm
Add documentation text about majority checking
add mnesia_majority_test suite
where_to_wlock optimization + change_table_majority/2
bug in mnesia_tm:needs_majority/2
optimize sticky_lock maj. check
check majority for sticky locks
...
Diffstat (limited to 'lib/kernel/src')
26 files changed, 1719 insertions, 458 deletions
diff --git a/lib/kernel/src/application.erl b/lib/kernel/src/application.erl index 2a193affd4..fa3a4c3d36 100644 --- a/lib/kernel/src/application.erl +++ b/lib/kernel/src/application.erl @@ -32,20 +32,30 @@ %%%----------------------------------------------------------------- +-type start_type() :: 'normal' + | {'takeover', Node :: node()} + | {'failover', Node :: node()}. -type restart_type() :: 'permanent' | 'transient' | 'temporary'. --type application_opt() :: {'description', string()} - | {'vsn', string()} - | {'id', string()} - | {'modules', [atom() | {atom(), any()}]} - | {'registered', [atom()]} - | {'applications', [atom()]} - | {'included_applications', [atom()]} - | {'env', [{atom(), any()}]} - | {'start_phases', [{atom(), any()}] | 'undefined'} - | {'maxT', timeout()} % max timeout - | {'maxP', integer() | 'infinity'} % max processes - | {'mod', {atom(), any()}}. --type application_spec() :: {'application', atom(), [application_opt()]}. +-type application_opt() :: {'description', Description :: string()} + | {'vsn', Vsn :: string()} + | {'id', Id :: string()} + | {'modules', [(Module :: module()) | + {Module :: module(), Version :: term()}]} + | {'registered', Names :: [Name :: atom()]} + | {'applications', [Application :: atom()]} + | {'included_applications', [Application :: atom()]} + | {'env', [{Par :: atom(), Val :: term()}]} + | {'start_phases', + [{Phase :: atom(), PhaseArgs :: term()}] | 'undefined'} + | {'maxT', MaxT :: timeout()} % max timeout + | {'maxP', + MaxP :: pos_integer() | 'infinity'} % max processes + | {'mod', Start :: {Module :: module(), StartArgs :: term()}}. +-type application_spec() :: {'application', + Application :: atom(), + AppSpecKeys :: [application_opt()]}. + +-type(tuple_of(_T) :: tuple()). %%------------------------------------------------------------------ @@ -61,16 +71,29 @@ behaviour_info(_Other) -> %%% application_master. %%%----------------------------------------------------------------- --spec load(Application :: atom() | application_spec()) -> - 'ok' | {'error', term()}. +-spec load(AppDescr) -> 'ok' | {'error', Reason} when + AppDescr :: Application | (AppSpec :: application_spec()), + Application :: atom(), + Reason :: term(). load(Application) -> - load(Application, []). - --spec load(Application :: atom() | application_spec(), - Distributed :: any()) -> 'ok' | {'error', term()}. + load1(Application, []). + +-spec load(AppDescr, Distributed) -> 'ok' | {'error', Reason} when + AppDescr :: Application | (AppSpec :: application_spec()), + Application :: atom(), + Distributed :: {Application,Nodes} + | {Application,Time,Nodes} + | 'default', + Nodes :: [node() | tuple_of(node())], + Time :: pos_integer(), + Reason :: term(). load(Application, DistNodes) -> + load1(Application, DistNodes). + +%% Workaround due to specs. +load1(Application, DistNodes) -> case application_controller:load_application(Application) of ok when DistNodes =/= [] -> AppName = get_appl_name(Application), @@ -85,18 +108,24 @@ load(Application, DistNodes) -> Else end. --spec unload(Application :: atom()) -> 'ok' | {'error', term()}. +-spec unload(Application) -> 'ok' | {'error', Reason} when + Application :: atom(), + Reason :: term(). unload(Application) -> application_controller:unload_application(Application). --spec start(Application :: atom()) -> 'ok' | {'error', term()}. +-spec start(Application) -> 'ok' | {'error', Reason} when + Application :: atom(), + Reason :: term(). start(Application) -> start(Application, temporary). --spec start(Application :: atom() | application_spec(), - RestartType :: restart_type()) -> any(). +-spec start(Application, Type) -> 'ok' | {'error', Reason} when + Application :: atom(), + Type :: restart_type(), + Reason :: term(). start(Application, RestartType) -> case load(Application) of @@ -120,12 +149,18 @@ start_boot(Application) -> start_boot(Application, RestartType) -> application_controller:start_boot_application(Application, RestartType). --spec takeover(Application :: atom(), RestartType :: restart_type()) -> any(). +-spec takeover(Application, Type) -> 'ok' | {'error', Reason} when + Application :: atom(), + Type :: restart_type(), + Reason :: term(). takeover(Application, RestartType) -> dist_ac:takeover_application(Application, RestartType). --spec permit(Application :: atom(), Bool :: boolean()) -> 'ok' | {'error', term()}. +-spec permit(Application, Permission) -> 'ok' | {'error', Reason} when + Application :: atom(), + Permission :: boolean(), + Reason :: term(). permit(Application, Bool) -> case Bool of @@ -142,105 +177,146 @@ permit(Application, Bool) -> LocalResult end. --spec stop(Application :: atom()) -> 'ok' | {'error', term()}. +-spec stop(Application) -> 'ok' | {'error', Reason} when + Application :: atom(), + Reason :: term(). stop(Application) -> application_controller:stop_application(Application). --spec which_applications() -> [{atom(), string(), string()}]. +-spec which_applications() -> [{Application, Description, Vsn}] when + Application :: atom(), + Description :: string(), + Vsn :: string(). which_applications() -> application_controller:which_applications(). --spec which_applications(timeout()) -> [{atom(), string(), string()}]. +-spec which_applications(Timeout) -> [{Application, Description, Vsn}] when + Timeout :: timeout(), + Application :: atom(), + Description :: string(), + Vsn :: string(). which_applications(infinity) -> application_controller:which_applications(infinity); which_applications(Timeout) when is_integer(Timeout), Timeout>=0 -> application_controller:which_applications(Timeout). --spec loaded_applications() -> [{atom(), string(), string()}]. +-spec loaded_applications() -> [{Application, Description, Vsn}] when + Application :: atom(), + Description :: string(), + Vsn :: string(). loaded_applications() -> application_controller:loaded_applications(). --spec info() -> any(). +-spec info() -> term(). info() -> application_controller:info(). --spec set_env(Application :: atom(), Key :: atom(), Value :: any()) -> 'ok'. +-spec set_env(Application, Par, Val) -> 'ok' when + Application :: atom(), + Par :: atom(), + Val :: term(). set_env(Application, Key, Val) -> application_controller:set_env(Application, Key, Val). --spec set_env(Application :: atom(), Key :: atom(), - Value :: any(), Timeout :: timeout()) -> 'ok'. +-spec set_env(Application, Par, Val, Timeout) -> 'ok' when + Application :: atom(), + Par :: atom(), + Val :: term(), + Timeout :: timeout(). set_env(Application, Key, Val, infinity) -> application_controller:set_env(Application, Key, Val, infinity); set_env(Application, Key, Val, Timeout) when is_integer(Timeout), Timeout>=0 -> application_controller:set_env(Application, Key, Val, Timeout). --spec unset_env(atom(), atom()) -> 'ok'. +-spec unset_env(Application, Par) -> 'ok' when + Application :: atom(), + Par :: atom(). unset_env(Application, Key) -> application_controller:unset_env(Application, Key). --spec unset_env(atom(), atom(), timeout()) -> 'ok'. +-spec unset_env(Application, Par, Timeout) -> 'ok' when + Application :: atom(), + Par :: atom(), + Timeout :: timeout(). unset_env(Application, Key, infinity) -> application_controller:unset_env(Application, Key, infinity); unset_env(Application, Key, Timeout) when is_integer(Timeout), Timeout>=0 -> application_controller:unset_env(Application, Key, Timeout). --spec get_env(atom()) -> 'undefined' | {'ok', term()}. +-spec get_env(Par) -> 'undefined' | {'ok', Val} when + Par :: atom(), + Val :: term(). get_env(Key) -> application_controller:get_pid_env(group_leader(), Key). --spec get_env(atom(), atom()) -> 'undefined' | {'ok', term()}. +-spec get_env(Application, Par) -> 'undefined' | {'ok', Val} when + Application :: atom(), + Par :: atom(), + Val :: term(). get_env(Application, Key) -> application_controller:get_env(Application, Key). --spec get_all_env() -> [{atom(), any()}]. +-spec get_all_env() -> Env when + Env :: [{Par :: atom(), Val :: term()}]. get_all_env() -> application_controller:get_pid_all_env(group_leader()). --spec get_all_env(atom()) -> [{atom(), any()}]. +-spec get_all_env(Application) -> Env when + Application :: atom(), + Env :: [{Par :: atom(), Val :: term()}]. get_all_env(Application) -> application_controller:get_all_env(Application). --spec get_key(atom()) -> 'undefined' | {'ok', term()}. +-spec get_key(Key) -> 'undefined' | {'ok', Val} when + Key :: atom(), + Val :: term(). get_key(Key) -> application_controller:get_pid_key(group_leader(), Key). --spec get_key(atom(), atom()) -> 'undefined' | {'ok', term()}. +-spec get_key(Application, Key) -> 'undefined' | {'ok', Val} when + Application :: atom(), + Key :: atom(), + Val :: term(). get_key(Application, Key) -> application_controller:get_key(Application, Key). --spec get_all_key() -> 'undefined' | [] | {'ok', [{atom(),any()},...]}. +-spec get_all_key() -> [] | {'ok', Keys} when + Keys :: [{Key :: atom(),Val :: term()},...]. get_all_key() -> application_controller:get_pid_all_key(group_leader()). --spec get_all_key(atom()) -> 'undefined' | {'ok', [{atom(),any()},...]}. +-spec get_all_key(Application) -> 'undefined' | Keys when + Application :: atom(), + Keys :: {'ok', [{Key :: atom(),Val :: term()},...]}. get_all_key(Application) -> application_controller:get_all_key(Application). --spec get_application() -> 'undefined' | {'ok', atom()}. +-spec get_application() -> 'undefined' | {'ok', Application} when + Application :: atom(). get_application() -> application_controller:get_application(group_leader()). --spec get_application(Pid :: pid()) -> 'undefined' | {'ok', atom()} - ; (Module :: atom()) -> 'undefined' | {'ok', atom()}. +-spec get_application(PidOrModule) -> 'undefined' | {'ok', Application} when + PidOrModule :: (Pid :: pid()) | (Module :: module()), + Application :: atom(). get_application(Pid) when is_pid(Pid) -> case process_info(Pid, group_leader) of @@ -252,8 +328,8 @@ get_application(Pid) when is_pid(Pid) -> get_application(Module) when is_atom(Module) -> application_controller:get_application_module(Module). --spec start_type() -> 'undefined' | 'local' | 'normal' - | {'takeover', node()} | {'failover', node()}. +-spec start_type() -> StartType | 'undefined' | 'local' when + StartType :: start_type(). start_type() -> application_controller:start_type(group_leader()). diff --git a/lib/kernel/src/auth.erl b/lib/kernel/src/auth.erl index 5c7fe2421d..25c88a4e1d 100644 --- a/lib/kernel/src/auth.erl +++ b/lib/kernel/src/auth.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2010. All Rights Reserved. +%% Copyright Ericsson AB 1996-2011. 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 @@ -57,7 +57,8 @@ start_link() -> %%--Deprecated interface------------------------------------------------ --spec is_auth(Node :: node()) -> 'yes' | 'no'. +-spec is_auth(Node) -> 'yes' | 'no' when + Node :: Node :: node(). is_auth(Node) -> case net_adm:ping(Node) of @@ -65,12 +66,15 @@ is_auth(Node) -> pang -> no end. --spec cookie() -> cookie(). +-spec cookie() -> Cookie when + Cookie :: cookie(). cookie() -> get_cookie(). --spec cookie(Cookies :: [cookie(),...] | cookie()) -> 'true'. +-spec cookie(TheCookie) -> 'true' when + TheCookie :: Cookie | [Cookie], + Cookie :: cookie(). cookie([Cookie]) -> set_cookie(Cookie); @@ -82,7 +86,9 @@ cookie(Cookie) -> node_cookie([Node, Cookie]) -> node_cookie(Node, Cookie). --spec node_cookie(Node :: node(), Cookie :: cookie()) -> 'yes' | 'no'. +-spec node_cookie(Node, Cookie) -> 'yes' | 'no' when + Node :: node(), + Cookie :: cookie(). node_cookie(Node, Cookie) -> set_cookie(Node, Cookie), diff --git a/lib/kernel/src/disk_log.erl b/lib/kernel/src/disk_log.erl index 7f1b5f9ec6..9b8d2db437 100644 --- a/lib/kernel/src/disk_log.erl +++ b/lib/kernel/src/disk_log.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2009. All Rights Reserved. +%% Copyright Ericsson AB 1997-2011. 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 @@ -70,9 +70,10 @@ %%% Contract type specifications %%%---------------------------------------------------------------------- +-opaque continuation() :: #continuation{}. + -type bytes() :: binary() | [byte()]. --type log() :: term(). % XXX: refine -type file_error() :: term(). % XXX: refine -type invalid_header() :: term(). % XXX: refine @@ -87,27 +88,30 @@ -type open_error_rsn() :: 'no_such_log' | {'badarg', term()} - | {'size_mismatch', dlog_size(), dlog_size()} - | {'arg_mismatch', dlog_optattr(), term(), term()} - | {'name_already_open', log()} - | {'open_read_write', log()} - | {'open_read_only', log()} - | {'need_repair', log()} - | {'not_a_log_file', string()} - | {'invalid_index_file', string()} + | {'size_mismatch', CurrentSize :: dlog_size(), + NewSize :: dlog_size()} + | {'arg_mismatch', OptionName :: dlog_optattr(), + CurrentValue :: term(), Value :: term()} + | {'name_already_open', Log :: log()} + | {'open_read_write', Log :: log()} + | {'open_read_only', Log :: log()} + | {'need_repair', Log :: log()} + | {'not_a_log_file', FileName :: file:filename()} + | {'invalid_index_file', FileName :: file:filename()} | {'invalid_header', invalid_header()} | {'file_error', file:filename(), file_error()} - | {'node_already_open', log()}. + | {'node_already_open', Log :: log()}. -type dist_error_rsn() :: 'nodedown' | open_error_rsn(). --type ret() :: {'ok', log()} - | {'repaired', log(), {'recovered', non_neg_integer()}, - {'badbytes', non_neg_integer()}}. +-type ret() :: {'ok', Log :: log()} + | {'repaired', Log :: log(), + {'recovered', Rec :: non_neg_integer()}, + {'badbytes', Bad :: non_neg_integer()}}. -type open_ret() :: ret() | {'error', open_error_rsn()}. -type dist_open_ret() :: {[{node(), ret()}], [{node(), {'error', dist_error_rsn()}}]}. --type all_open_ret() :: open_ret() | dist_open_ret(). --spec open(Args :: dlog_options()) -> all_open_ret(). +-spec open(ArgL) -> open_ret() | dist_open_ret() when + ArgL :: dlog_options(). open(A) -> disk_log_server:open(check_arg(A, #arg{options = A})). @@ -116,40 +120,57 @@ open(A) -> | {'full', log()} | {'invalid_header', invalid_header()} | {'file_error', file:filename(), file_error()}. --spec log(Log :: log(), Term :: term()) -> 'ok' | {'error', log_error_rsn()}. +-spec log(Log, Term) -> ok | {error, Reason :: log_error_rsn()} when + Log :: log(), + Term :: term(). log(Log, Term) -> req(Log, {log, term_to_binary(Term)}). --spec blog(Log :: log(), Bytes :: bytes()) -> 'ok' | {'error', log_error_rsn()}. +-spec blog(Log, Bytes) -> ok | {error, Reason :: log_error_rsn()} when + Log :: log(), + Bytes :: bytes(). blog(Log, Bytes) -> req(Log, {blog, check_bytes(Bytes)}). --spec log_terms(Log :: log(), Terms :: [term()]) -> 'ok' | {'error', term()}. +-spec log_terms(Log, TermList) -> ok | {error, Resaon :: log_error_rsn()} when + Log :: log(), + TermList :: [term()]. log_terms(Log, Terms) -> Bs = terms2bins(Terms), req(Log, {log, Bs}). --spec blog_terms(Log :: log(), Bytes :: [bytes()]) -> 'ok' | {'error', term()}. +-spec blog_terms(Log, BytesList) -> + ok | {error, Reason :: log_error_rsn()} when + Log :: log(), + BytesList :: [bytes()]. blog_terms(Log, Bytess) -> Bs = check_bytes_list(Bytess, Bytess), req(Log, {blog, Bs}). -type notify_ret() :: 'ok' | {'error', 'no_such_log'}. --spec alog(Log :: log(), Term :: term()) -> notify_ret(). +-spec alog(Log, Term) -> notify_ret() when + Log :: log(), + Term :: term(). alog(Log, Term) -> notify(Log, {alog, term_to_binary(Term)}). --spec alog_terms(Log :: log(), Terms :: [term()]) -> notify_ret(). +-spec alog_terms(Log, TermList) -> notify_ret() when + Log :: log(), + TermList :: [term()]. alog_terms(Log, Terms) -> Bs = terms2bins(Terms), notify(Log, {alog, Bs}). --spec balog(Log :: log(), Bytes :: bytes()) -> notify_ret(). +-spec balog(Log, Bytes) -> notify_ret() when + Log :: log(), + Bytes :: bytes(). balog(Log, Bytes) -> notify(Log, {balog, check_bytes(Bytes)}). --spec balog_terms(Log :: log(), Bytes :: [bytes()]) -> notify_ret(). +-spec balog_terms(Log, ByteList) -> notify_ret() when + Log :: log(), + ByteList :: [bytes()]. balog_terms(Log, Bytess) -> Bs = check_bytes_list(Bytess, Bytess), notify(Log, {balog, Bs}). @@ -157,18 +178,22 @@ balog_terms(Log, Bytess) -> -type close_error_rsn() ::'no_such_log' | 'nonode' | {'file_error', file:filename(), file_error()}. --spec close(Log :: log()) -> 'ok' | {'error', close_error_rsn()}. +-spec close(Log) -> 'ok' | {'error', close_error_rsn()} when + Log :: log(). close(Log) -> req(Log, close). -type lclose_error_rsn() :: 'no_such_log' | {'file_error', file:filename(), file_error()}. --spec lclose(Log :: log()) -> 'ok' | {'error', lclose_error_rsn()}. +-spec lclose(Log) -> 'ok' | {'error', lclose_error_rsn()} when + Log :: log(). lclose(Log) -> lclose(Log, node()). --spec lclose(Log :: log(), Node :: node()) -> 'ok' | {'error', lclose_error_rsn()}. +-spec lclose(Log, Node) -> 'ok' | {'error', lclose_error_rsn()} when + Log :: log(), + Node :: node(). lclose(Log, Node) -> lreq(Log, close, Node). @@ -178,29 +203,49 @@ lclose(Log, Node) -> | {'invalid_header', invalid_header()} | {'file_error', file:filename(), file_error()}. --spec truncate(Log :: log()) -> 'ok' | {'error', trunc_error_rsn()}. +-spec truncate(Log) -> 'ok' | {'error', trunc_error_rsn()} when + Log :: log(). truncate(Log) -> req(Log, {truncate, none, truncate, 1}). --spec truncate(Log :: log(), Head :: term()) -> 'ok' | {'error', trunc_error_rsn()}. +-spec truncate(Log, Head) -> 'ok' | {'error', trunc_error_rsn()} when + Log :: log(), + Head :: term(). truncate(Log, Head) -> req(Log, {truncate, {ok, term_to_binary(Head)}, truncate, 2}). --spec btruncate(Log :: log(), Head :: bytes()) -> 'ok' | {'error', trunc_error_rsn()}. +-spec btruncate(Log, BHead) -> 'ok' | {'error', trunc_error_rsn()} when + Log :: log(), + BHead :: bytes(). btruncate(Log, Head) -> req(Log, {truncate, {ok, check_bytes(Head)}, btruncate, 2}). --spec reopen(Log :: log(), Filename :: file:filename()) -> 'ok' | {'error', term()}. +-type reopen_error_rsn() :: no_such_log + | nonode + | {read_only_mode, log()} + | {blocked_log, log()} + | {same_file_name, log()} | + {invalid_index_file, file:filename()} + | {invalid_header, invalid_header()} + | {'file_error', file:filename(), file_error()}. + +-spec reopen(Log, File) -> 'ok' | {'error', reopen_error_rsn()} when + Log :: log(), + File :: file:filename(). reopen(Log, NewFile) -> req(Log, {reopen, NewFile, none, reopen, 2}). --spec reopen(Log :: log(), Filename :: file:filename(), Head :: term()) -> - 'ok' | {'error', term()}. +-spec reopen(Log, File, Head) -> 'ok' | {'error', reopen_error_rsn()} when + Log :: log(), + File :: file:filename(), + Head :: term(). reopen(Log, NewFile, NewHead) -> req(Log, {reopen, NewFile, {ok, term_to_binary(NewHead)}, reopen, 3}). --spec breopen(Log :: log(), Filename :: file:filename(), Head :: bytes()) -> - 'ok' | {'error', term()}. +-spec breopen(Log, File, BHead) -> 'ok' | {'error', reopen_error_rsn()} when + Log :: log(), + File :: file:filename(), + BHead :: bytes(). breopen(Log, NewFile, NewHead) -> req(Log, {reopen, NewFile, {ok, check_bytes(NewHead)}, breopen, 3}). @@ -210,21 +255,36 @@ breopen(Log, NewFile, NewHead) -> | {'invalid_header', invalid_header()} | {'file_error', file:filename(), file_error()}. --spec inc_wrap_file(Log :: log()) -> 'ok' | {'error', inc_wrap_error_rsn()}. +-spec inc_wrap_file(Log) -> 'ok' | {'error', inc_wrap_error_rsn()} when + Log :: log(). inc_wrap_file(Log) -> req(Log, inc_wrap_file). --spec change_size(Log :: log(), Size :: dlog_size()) -> 'ok' | {'error', term()}. +-spec change_size(Log, Size) -> 'ok' | {'error', Reason} when + Log :: log(), + Size :: dlog_size(), + Reason :: no_such_log | nonode | {read_only_mode, Log} + | {blocked_log, Log} + | {new_size_too_small, CurrentSize :: pos_integer()} + | {badarg, size} + | {file_error, file:filename(), file_error()}. change_size(Log, NewSize) -> req(Log, {change_size, NewSize}). --spec change_notify(Log :: log(), Pid :: pid(), Notify :: boolean()) -> - 'ok' | {'error', term()}. +-spec change_notify(Log, Owner, Notify) -> 'ok' | {'error', Reason} when + Log :: log(), + Owner :: pid(), + Notify :: boolean(), + Reason :: no_such_log | nonode | {blocked_log, Log} + | {badarg, notify} | {not_owner, Owner}. change_notify(Log, Pid, NewNotify) -> req(Log, {change_notify, Pid, NewNotify}). --spec change_header(Log :: log(), Head :: {atom(), term()}) -> - 'ok' | {'error', term()}. +-spec change_header(Log, Header) -> 'ok' | {'error', Reason} when + Log :: log(), + Header :: {head, dlog_head_opt()} | {head_func, mfa()}, + Reason :: no_such_log | nonode | {read_only_mode, Log} + | {blocked_log, Log} | {badarg, head}. change_header(Log, NewHead) -> req(Log, {change_header, NewHead}). @@ -232,17 +292,21 @@ change_header(Log, NewHead) -> | {'blocked_log', log()} | {'file_error', file:filename(), file_error()}. --spec sync(Log :: log()) -> 'ok' | {'error', sync_error_rsn()}. +-spec sync(Log) -> 'ok' | {'error', sync_error_rsn()} when + Log :: log(). sync(Log) -> req(Log, sync). -type block_error_rsn() :: 'no_such_log' | 'nonode' | {'blocked_log', log()}. --spec block(Log :: log()) -> 'ok' | {'error', block_error_rsn()}. +-spec block(Log) -> 'ok' | {'error', block_error_rsn()} when + Log :: log(). block(Log) -> block(Log, true). --spec block(Log :: log(), QueueLogRecords :: boolean()) -> 'ok' | {'error', term()}. +-spec block(Log, QueueLogRecords) -> 'ok' | {'error', block_error_rsn()} when + Log :: log(), + QueueLogRecords :: boolean(). block(Log, QueueLogRecords) -> req(Log, {block, QueueLogRecords}). @@ -250,19 +314,46 @@ block(Log, QueueLogRecords) -> | {'not_blocked', log()} | {'not_blocked_by_pid', log()}. --spec unblock(Log :: log()) -> 'ok' | {'error', unblock_error_rsn()}. +-spec unblock(Log) -> 'ok' | {'error', unblock_error_rsn()} when + Log :: log(). unblock(Log) -> req(Log, unblock). --spec format_error(Error :: term()) -> string(). +-spec format_error(Error) -> io_lib:chars() when + Error :: term(). format_error(Error) -> do_format_error(Error). --spec info(Log :: log()) -> [{atom(), any()}] | {'error', term()}. +-type dlog_info() :: {name, Log :: log()} + | {file, File :: file:filename()} + | {type, Type :: dlog_type()} + | {format, Format :: dlog_format()} + | {size, Size :: dlog_size()} + | {mode, Mode :: dlog_mode()} + | {owners, [{pid(), Notify :: boolean()}]} + | {users, Users :: non_neg_integer()} + | {status, Status :: + ok | {blocked, QueueLogRecords :: boolean()}} + | {node, Node :: node()} + | {distributed, Dist :: local | [node()]} + | {head, Head :: none | {head, term()} | mfa()} + | {no_written_items, NoWrittenItems ::non_neg_integer()} + | {full, Full :: boolean} + | {no_current_bytes, non_neg_integer()} + | {no_current_items, non_neg_integer()} + | {no_items, non_neg_integer()} + | {current_file, pos_integer()} + | {no_overflows, {SinceLogWasOpened :: non_neg_integer(), + SinceLastInfo :: non_neg_integer()}}. +-spec info(Log) -> InfoList | {'error', no_such_log} when + Log :: log(), + InfoList :: [dlog_info()]. info(Log) -> sreq(Log, info). --spec pid2name(Pid :: pid()) -> {'ok', log()} | 'undefined'. +-spec pid2name(Pid) -> {'ok', Log} | 'undefined' when + Pid :: pid(), + Log :: log(). pid2name(Pid) -> disk_log_server:start(), case ets:lookup(?DISK_LOG_PID_TABLE, Pid) of @@ -274,13 +365,31 @@ pid2name(Pid) -> %% It retuns a {Cont2, ObjList} | eof | {error, Reason} %% The initial continuation is the atom 'start' --spec chunk(Log :: log(), Cont :: any()) -> - {'error', term()} | 'eof' | {any(), [any()]} | {any(), [any()], integer()}. +-type chunk_error_rsn() :: no_such_log + | {format_external, log()} + | {blocked_log, log()} + | {badarg, continuation} + | {not_internal_wrap, log()} + | {corrupt_log_file, FileName :: file:filename()} + | {file_error, file:filename(), file_error()}. + +-type chunk_ret() :: {Continuation2 :: continuation(), Terms :: [term()]} + | {Continuation2 :: continuation(), + Terms :: [term()], + Badbytes :: non_neg_integer()} + | eof + | {error, Reason :: chunk_error_rsn()}. + +-spec chunk(Log, Continuation) -> chunk_ret() when + Log :: log(), + Continuation :: start | continuation(). chunk(Log, Cont) -> chunk(Log, Cont, infinity). --spec chunk(Log :: log(), Cont :: any(), N :: pos_integer() | 'infinity') -> - {'error', term()} | 'eof' | {any(), [any()]} | {any(), [any()], integer()}. +-spec chunk(Log, Continuation, N) -> chunk_ret() when + Log :: log(), + Continuation :: start | continuation(), + N :: pos_integer() | infinity. chunk(Log, Cont, infinity) -> %% There cannot be more than ?MAX_CHUNK_SIZE terms in a chunk. ichunk(Log, Cont, ?MAX_CHUNK_SIZE); @@ -346,13 +455,24 @@ ichunk_bad_end([B | Bs], Mode, Log, C, Bad, A) -> ichunk_bad_end(Bs, Mode, Log, C, Bad, [T | A]) end. --spec bchunk(Log :: log(), Cont :: any()) -> - {'error', any()} | 'eof' | {any(), [binary()]} | {any(), [binary()], integer()}. +-type bchunk_ret() :: {Continuation2 :: continuation(), + Binaries :: [binary()]} + | {Continuation2 :: continuation(), + Binaries :: [binary()], + Badbytes :: non_neg_integer()} + | eof + | {error, Reason :: chunk_error_rsn()}. + +-spec bchunk(Log, Continuation) -> bchunk_ret() when + Log :: log(), + Continuation :: start | continuation(). bchunk(Log, Cont) -> bchunk(Log, Cont, infinity). --spec bchunk(Log :: log(), Cont :: any(), N :: 'infinity' | pos_integer()) -> - {'error', any()} | 'eof' | {any(), [binary()]} | {any(), [binary()], integer()}. +-spec bchunk(Log, Continuation, N) -> bchunk_ret() when + Log :: log(), + Continuation :: start | continuation(), + N :: pos_integer() | infinity. bchunk(Log, Cont, infinity) -> %% There cannot be more than ?MAX_CHUNK_SIZE terms in a chunk. bichunk(Log, Cont, ?MAX_CHUNK_SIZE); @@ -375,8 +495,14 @@ bichunk_end({C = #continuation{}, R, Bad}) -> bichunk_end(R) -> R. --spec chunk_step(Log :: log(), Cont :: any(), N :: integer()) -> - {'ok', any()} | {'error', term()}. +-spec chunk_step(Log, Continuation, Step) -> + {'ok', any()} | {'error', Reason} when + Log :: log(), + Continuation :: start | continuation(), + Step :: integer(), + Reason :: no_such_log | end_of_log | {format_external, Log} + | {blocked_log, Log} | {badarg, continuation} + | {file_error, file:filename(), file_error()}. chunk_step(Log, Cont, N) when is_integer(N) -> ichunk_step(Log, Cont, N). @@ -387,14 +513,18 @@ ichunk_step(_Log, More, N) when is_record(More, continuation) -> ichunk_step(_Log, _, _) -> {error, {badarg, continuation}}. --spec chunk_info(More :: any()) -> - [{'node', node()},...] | {'error', {'no_continuation', any()}}. +-spec chunk_info(Continuation) -> InfoList | {error, Reason} when + Continuation :: continuation(), + InfoList :: [{node, Node :: node()}, ...], + Reason :: {no_continuation, Continuation}. chunk_info(More = #continuation{}) -> [{node, node(More#continuation.pid)}]; chunk_info(BadCont) -> {error, {no_continuation, BadCont}}. --spec accessible_logs() -> {[_], [_]}. +-spec accessible_logs() -> {[LocalLog], [DistributedLog]} when + LocalLog :: log(), + DistributedLog :: log(). accessible_logs() -> disk_log_server:accessible_logs(). diff --git a/lib/kernel/src/disk_log.hrl b/lib/kernel/src/disk_log.hrl index 9a94d4d3b9..259967650f 100644 --- a/lib/kernel/src/disk_log.hrl +++ b/lib/kernel/src/disk_log.hrl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2010. All Rights Reserved. +%% Copyright Ericsson AB 1997-2011. 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 @@ -53,18 +53,34 @@ %% Types -- alphabetically %%------------------------------------------------------------------------ +-type dlog_byte() :: [dlog_byte()] | byte(). -type dlog_format() :: 'external' | 'internal'. -type dlog_format_type() :: 'halt_ext' | 'halt_int' | 'wrap_ext' | 'wrap_int'. -type dlog_head() :: 'none' | {'ok', binary()} | mfa(). +-type dlog_head_opt() :: none | term() | binary() | [dlog_byte()]. +-type log() :: term(). % XXX: refine -type dlog_mode() :: 'read_only' | 'read_write'. -type dlog_name() :: atom() | string(). -type dlog_optattr() :: 'name' | 'file' | 'linkto' | 'repair' | 'type' | 'format' | 'size' | 'distributed' | 'notify' | 'head' | 'head_func' | 'mode'. --type dlog_options() :: [{dlog_optattr(), any()}]. +-type dlog_option() :: {name, Log :: log()} + | {file, FileName :: file:filename()} + | {linkto, LinkTo :: none | pid()} + | {repair, Repair :: true | false | truncate} + | {type, Type :: dlog_type} + | {format, Format :: dlog_format()} + | {size, Size :: dlog_size()} + | {distributed, Nodes :: [node()]} + | {notify, boolean()} + | {head, Head :: dlog_head_opt()} + | {head_func, mfa()} + | {mode, Mode :: dlog_mode()}. +-type dlog_options() :: [dlog_option()]. -type dlog_repair() :: 'truncate' | boolean(). -type dlog_size() :: 'infinity' | pos_integer() - | {pos_integer(), pos_integer()}. + | {MaxNoBytes :: pos_integer(), + MaxNoFiles :: pos_integer()}. -type dlog_status() :: 'ok' | {'blocked', 'false' | [_]}. %QueueLogRecords -type dlog_type() :: 'halt' | 'wrap'. @@ -75,7 +91,7 @@ %% record of args for open -record(arg, {name = 0, version = undefined, - file = none :: 'none' | string(), + file = none :: 'none' | file:filename(), repair = true :: dlog_repair(), size = infinity :: dlog_size(), type = halt :: dlog_type(), diff --git a/lib/kernel/src/erl_boot_server.erl b/lib/kernel/src/erl_boot_server.erl index b4c5f5e27c..0d68d3e198 100644 --- a/lib/kernel/src/erl_boot_server.erl +++ b/lib/kernel/src/erl_boot_server.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2010. All Rights Reserved. +%% Copyright Ericsson AB 1996-2011. 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 @@ -59,7 +59,11 @@ -type ip4_address() :: {0..255,0..255,0..255,0..255}. --spec start(Slaves :: [atom()]) -> {'ok', pid()} | {'error', any()}. +-spec start(Slaves) -> {'ok', Pid} | {'error', What} when + Slaves :: [Host], + Host :: atom(), + Pid :: pid(), + What :: any(). start(Slaves) -> case check_arg(Slaves) of @@ -69,7 +73,11 @@ start(Slaves) -> {error, {badarg, Slaves}} end. --spec start_link(Slaves :: [atom()]) -> {'ok', pid()} | {'error', any()}. +-spec start_link(Slaves) -> {'ok', Pid} | {'error', What} when + Slaves :: [Host], + Host :: atom(), + Pid :: pid(), + What :: any(). start_link(Slaves) -> case check_arg(Slaves) of @@ -95,7 +103,10 @@ check_arg([], Result) -> check_arg(_, _Result) -> error. --spec add_slave(Slave :: atom()) -> 'ok' | {'error', any()}. +-spec add_slave(Slave) -> 'ok' | {'error', What} when + Slave :: Host, + Host :: atom(), + What :: any(). add_slave(Slave) -> case inet:getaddr(Slave, inet) of @@ -105,7 +116,10 @@ add_slave(Slave) -> {error, {badarg, Slave}} end. --spec delete_slave(Slave :: atom()) -> 'ok' | {'error', any()}. +-spec delete_slave(Slave) -> 'ok' | {'error', What} when + Slave :: Host, + Host :: atom(), + What :: any(). delete_slave(Slave) -> case inet:getaddr(Slave, inet) of @@ -131,7 +145,9 @@ add_subnet(Mask, Addr) when is_tuple(Mask), is_tuple(Addr) -> delete_subnet(Mask, Addr) when is_tuple(Mask), is_tuple(Addr) -> gen_server:call(boot_server, {delete, {Mask, Addr}}). --spec which_slaves() -> [atom()]. +-spec which_slaves() -> Slaves when + Slaves :: [Host], + Host :: atom(). which_slaves() -> gen_server:call(boot_server, which). diff --git a/lib/kernel/src/erl_ddll.erl b/lib/kernel/src/erl_ddll.erl index ce64589a29..646cac99c5 100644 --- a/lib/kernel/src/erl_ddll.erl +++ b/lib/kernel/src/erl_ddll.erl @@ -44,14 +44,18 @@ start() -> stop() -> ok. --spec load_driver(Path :: path(), Driver :: driver()) -> - 'ok' | {'error', any()}. +-spec load_driver(Path, Name) -> 'ok' | {'error', ErrorDesc} when + Path :: path(), + Name :: driver(), + ErrorDesc :: term(). load_driver(Path, Driver) -> do_load_driver(Path, Driver, [{driver_options,[kill_ports]}]). --spec load(Path :: path(), Driver :: driver()) -> - 'ok' | {'error', any()}. +-spec load(Path, Name) -> 'ok' | {'error', ErrorDesc} when + Path :: path(), + Name :: driver(), + ErrorDesc ::term(). load(Path, Driver) -> do_load_driver(Path, Driver, []). @@ -100,30 +104,41 @@ do_unload_driver(Driver,Flags) -> end end. --spec unload_driver(Driver :: driver()) -> 'ok' | {'error', any()}. +-spec unload_driver(Name) -> 'ok' | {'error', ErrorDesc} when + Name :: driver(), + ErrorDesc :: term(). unload_driver(Driver) -> do_unload_driver(Driver,[{monitor,pending_driver},kill_ports]). --spec unload(Driver :: driver()) -> 'ok' | {'error', any()}. +-spec unload(Name) -> 'ok' | {'error', ErrorDesc} when + Name :: driver(), + ErrorDesc :: term(). unload(Driver) -> do_unload_driver(Driver,[]). --spec reload(Path :: path(), Driver :: driver()) -> - 'ok' | {'error', any()}. +-spec reload(Path, Name) -> 'ok' | {'error', ErrorDesc} when + Path :: path(), + Name :: driver(), + ErrorDesc :: pending_process | OpaqueError, + OpaqueError :: term(). reload(Path,Driver) -> do_load_driver(Path, Driver, [{reload,pending_driver}]). --spec reload_driver(Path :: path(), Driver :: driver()) -> - 'ok' | {'error', any()}. +-spec reload_driver(Path, Name) -> 'ok' | {'error', ErrorDesc} when + Path :: path(), + Name :: driver(), + ErrorDesc :: pending_process | OpaqueError, + OpaqueError :: term(). reload_driver(Path,Driver) -> do_load_driver(Path, Driver, [{reload,pending_driver}, {driver_options,[kill_ports]}]). --spec format_error(Code :: atom()) -> string(). +-spec format_error(ErrorDesc) -> string() when + ErrorDesc :: term(). format_error(Code) -> case Code of @@ -135,7 +150,10 @@ format_error(Code) -> erl_ddll:format_error_int(Code) end. --spec info(Driver :: driver()) -> [{atom(), any()}, ...]. +-spec info(Name) -> InfoList when + Name :: driver(), + InfoList :: [InfoItem, ...], + InfoItem :: {Tag :: atom(), Value :: term()}. info(Driver) -> [{processes, erl_ddll:info(Driver,processes)}, @@ -146,7 +164,12 @@ info(Driver) -> {awaiting_load, erl_ddll:info(Driver,awaiting_load)}, {awaiting_unload, erl_ddll:info(Driver,awaiting_unload)}]. --spec info() -> [{string(), [{atom(), any()}]}]. +-spec info() -> AllInfoList when + AllInfoList :: [DriverInfo], + DriverInfo :: {DriverName, InfoList}, + DriverName :: string(), + InfoList :: [InfoItem], + InfoItem :: {Tag :: atom(), Value :: term()}. info() -> {ok,DriverList} = erl_ddll:loaded_drivers(), diff --git a/lib/kernel/src/error_handler.erl b/lib/kernel/src/error_handler.erl index 6f69f4ccb9..e1f99bf417 100644 --- a/lib/kernel/src/error_handler.erl +++ b/lib/kernel/src/error_handler.erl @@ -28,8 +28,11 @@ -export([undefined_function/3, undefined_lambda/3, stub_function/3, breakpoint/3]). --spec undefined_function(Module :: atom(), Function :: atom(), Args :: [_]) -> - any(). +-spec undefined_function(Module, Function, Args) -> + any() when + Module :: atom(), + Function :: atom(), + Args :: list(). undefined_function(Module, Func, Args) -> case ensure_loaded(Module) of @@ -51,8 +54,10 @@ undefined_function(Module, Func, Args) -> crash(Module, Func, Args) end. --spec undefined_lambda(Module :: atom(), Function :: fun(), Args :: [_]) -> - any(). +-spec undefined_lambda(Module, Fun, Args) -> term() when + Module :: atom(), + Fun :: fun(), + Args :: list(). undefined_lambda(Module, Fun, Args) -> case ensure_loaded(Module) of diff --git a/lib/kernel/src/error_logger.erl b/lib/kernel/src/error_logger.erl index cafdc52e84..f94cca000f 100644 --- a/lib/kernel/src/error_logger.erl +++ b/lib/kernel/src/error_logger.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2009. All Rights Reserved. +%% Copyright Ericsson AB 1996-2011. 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 @@ -69,17 +69,22 @@ start_link() -> %% Used for simple messages; error or information. %%----------------------------------------------------------------- --spec error_msg(Format :: string()) -> 'ok'. +-spec error_msg(Format) -> 'ok' when + Format :: string(). error_msg(Format) -> error_msg(Format,[]). --spec error_msg(Format :: string(), Args :: list()) -> 'ok'. +-spec error_msg(Format, Data) -> 'ok' when + Format :: string(), + Data :: list(). error_msg(Format, Args) -> notify({error, group_leader(), {self(), Format, Args}}). --spec format(Format :: string(), Args :: list()) -> 'ok'. +-spec format(Format, Data) -> 'ok' when + Format :: string(), + Data :: list(). format(Format, Args) -> notify({error, group_leader(), {self(), Format, Args}}). @@ -90,12 +95,18 @@ format(Format, Args) -> %% The 'std_error' error_report type can always be used. %%----------------------------------------------------------------- --spec error_report(Report :: any()) -> 'ok'. +-type report() :: + [{Tag :: term(), Data :: term()} | term()] | string() | term(). + +-spec error_report(Report) -> 'ok' when + Report :: report(). error_report(Report) -> error_report(std_error, Report). --spec error_report(Type :: any(), Report :: any()) -> 'ok'. +-spec error_report(Type, Report) -> 'ok' when + Type :: term(), + Report :: report(). error_report(Type, Report) -> notify({error_report, group_leader(), {self(), Type, Report}}). @@ -109,12 +120,15 @@ error_report(Type, Report) -> %% mapped to std_info or std_error accordingly. %%----------------------------------------------------------------- --spec warning_report(Report :: any()) -> 'ok'. +-spec warning_report(Report) -> 'ok' when + Report :: report(). warning_report(Report) -> warning_report(std_warning, Report). --spec warning_report(Type :: any(), Report :: any()) -> 'ok'. +-spec warning_report(Type, Report) -> 'ok' when + Type :: any(), + Report :: report(). warning_report(Type, Report) -> {Tag, NType} = case error_logger:warning_map() of @@ -143,12 +157,15 @@ warning_report(Type, Report) -> %% other types of reports. %%----------------------------------------------------------------- --spec warning_msg(Format :: string()) -> 'ok'. +-spec warning_msg(Format) -> 'ok' when + Format :: string(). warning_msg(Format) -> warning_msg(Format,[]). --spec warning_msg(Format :: string(), Args :: list()) -> 'ok'. +-spec warning_msg(Format, Data) -> 'ok' when + Format :: string(), + Data :: list(). warning_msg(Format, Args) -> Tag = case error_logger:warning_map() of @@ -167,12 +184,15 @@ warning_msg(Format, Args) -> %% The 'std_info' info_report type can always be used. %%----------------------------------------------------------------- --spec info_report(Report :: any()) -> 'ok'. +-spec info_report(Report) -> 'ok' when + Report :: report(). info_report(Report) -> info_report(std_info, Report). --spec info_report(Type :: any(), Report :: any()) -> 'ok'. +-spec info_report(Type, Report) -> 'ok' when + Type :: any(), + Report :: report(). info_report(Type, Report) -> notify({info_report, group_leader(), {self(), Type, Report}}). @@ -182,12 +202,15 @@ info_report(Type, Report) -> %% information messages. %%----------------------------------------------------------------- --spec info_msg(Format :: string()) -> 'ok'. +-spec info_msg(Format) -> 'ok' when + Format :: string(). info_msg(Format) -> info_msg(Format,[]). --spec info_msg(Format :: string(), Args :: list()) -> 'ok'. +-spec info_msg(Format, Data) -> 'ok' when + Format :: string(), + Data :: list(). info_msg(Format, Args) -> notify({info_msg, group_leader(), {self(), Format, Args}}). @@ -223,17 +246,23 @@ swap_handler(silent) -> swap_handler(false) -> ok. % keep primitive event handler as-is --spec add_report_handler(Module :: atom()) -> any(). +-spec add_report_handler(Handler) -> any() when + Handler :: module(). add_report_handler(Module) when is_atom(Module) -> gen_event:add_handler(error_logger, Module, []). --spec add_report_handler(atom(), any()) -> any(). +-spec add_report_handler(Handler, Args) -> Result when + Handler :: module(), + Args :: gen_event:handler_args(), + Result :: gen_event:add_handler_ret(). add_report_handler(Module, Args) when is_atom(Module) -> gen_event:add_handler(error_logger, Module, Args). --spec delete_report_handler(Module :: atom()) -> any(). +-spec delete_report_handler(Handler) -> Result when + Handler :: module(), + Result :: gen_event:del_handler_ret(). delete_report_handler(Module) when is_atom(Module) -> gen_event:delete_handler(error_logger, Module, []). @@ -250,9 +279,16 @@ simple_logger() -> %% Log all errors to File for all eternity --spec logfile(Request :: {'open', string()}) -> 'ok' | {'error',any()} - ; (Request :: 'close') -> 'ok' | {'error', any()} - ; (Request :: 'filename') -> atom() | string() | {'error', any()}. +-type open_error() :: file:posix() | badarg | system_limit. + +-spec logfile(Request :: {open, Filename}) -> ok | {error, OpenReason} when + Filename ::file:name(), + OpenReason :: allready_have_logfile | open_error() + ; (Request :: close) -> ok | {error, CloseReason} when + CloseReason :: module_not_found + ; (Request :: filename) -> Filename | {error, FilenameReason} when + Filename :: file:name(), + FilenameReason :: no_log_file. logfile({open, File}) -> case lists:member(error_logger_file_h, @@ -280,7 +316,8 @@ logfile(filename) -> %% Possibly turn off all tty printouts, maybe we only want the errors %% to go to a file --spec tty(Flag :: boolean()) -> 'ok'. +-spec tty(Flag) -> 'ok' when + Flag :: boolean(). tty(true) -> Hs = gen_event:which_handlers(error_logger), diff --git a/lib/kernel/src/file.erl b/lib/kernel/src/file.erl index 88bcf9a9cc..f1a8aa9f77 100644 --- a/lib/kernel/src/file.erl +++ b/lib/kernel/src/file.erl @@ -79,15 +79,19 @@ -type file_info() :: #file_info{}. -type fd() :: #file_descriptor{}. -type io_device() :: pid() | fd(). --type location() :: integer() | {'bof', integer()} | {'cur', integer()} - | {'eof', integer()} | 'bof' | 'cur' | 'eof'. +-type location() :: integer() | {'bof', Offset :: integer()} + | {'cur', Offset :: integer()} + | {'eof', Offset :: integer()} | 'bof' | 'cur' | 'eof'. -type mode() :: 'read' | 'write' | 'append' | 'exclusive' | 'raw' | 'binary' - | {'delayed_write', non_neg_integer(), non_neg_integer()} - | 'delayed_write' | {'read_ahead', pos_integer()} + | {'delayed_write', + Size :: non_neg_integer(), + Delay :: non_neg_integer()} + | 'delayed_write' | {'read_ahead', Size :: pos_integer()} | 'read_ahead' | 'compressed' | {'encoding', unicode:encoding()}. --type name() :: string() | atom() | [name()] | binary(). +-type deep_list() :: [char() | atom() | deep_list()]. +-type name() :: string() | atom() | deep_list() | (RawFilename :: binary()). -type posix() :: 'eacces' | 'eagain' | 'ebadf' | 'ebusy' | 'edquot' | 'eexist' | 'efault' | 'efbig' | 'eintr' | 'einval' | 'eio' | 'eisdir' | 'eloop' | 'emfile' | 'emlink' @@ -96,10 +100,14 @@ | 'enotblk' | 'enotdir' | 'enotsup' | 'enxio' | 'eperm' | 'epipe' | 'erofs' | 'espipe' | 'esrch' | 'estale' | 'exdev'. --type bindings() :: any(). - --type date() :: {pos_integer(), pos_integer(), pos_integer()}. --type time() :: {non_neg_integer(), non_neg_integer(), non_neg_integer()}. +-type bindings() :: erl_eval:binding_struct(). + +-type date() :: {Year :: pos_integer(), + Month :: pos_integer(), + Day ::pos_integer()}. +-type time() :: {Hour :: non_neg_integer(), + Minute :: non_neg_integer(), + Second :: non_neg_integer()}. -type date_time() :: {date(), time()}. -type posix_file_advise() :: 'normal' | 'sequential' | 'random' | 'no_reuse' | 'will_need' | 'dont_need'. @@ -107,8 +115,10 @@ %%%----------------------------------------------------------------- %%% General functions --spec format_error(Reason :: posix() | {integer(), atom(), any()}) -> - string(). +-spec format_error(Reason) -> Chars when + Reason :: posix() | badarg | terminated | system_limit + | {Line :: integer(), Mod :: module(), Term :: term()}, + Chars :: string(). format_error({_Line, ?MODULE, undefined_script}) -> "no value returned from script"; @@ -129,7 +139,9 @@ format_error(terminated) -> format_error(ErrorId) -> erl_posix_msg:message(ErrorId). --spec pid2name(Pid :: pid()) -> {'ok', filename()} | 'undefined'. +-spec pid2name(Pid) -> {ok, Filename} | undefined when + Filename :: filename(), + Pid :: pid(). pid2name(Pid) when is_pid(Pid) -> case whereis(?FILE_SERVER) of @@ -148,42 +160,61 @@ pid2name(Pid) when is_pid(Pid) -> %%% File server functions. %%% Functions that do not operate on a single open file. %%% Stateless. --spec get_cwd() -> {'ok', filename()} | {'error', posix()}. +-spec get_cwd() -> {ok, Dir} | {error, Reason} when + Dir :: filename(), + Reason :: posix(). get_cwd() -> call(get_cwd, []). --spec get_cwd(Drive :: string()) -> {'ok', filename()} | {'error', posix()}. +-spec get_cwd(Drive) -> {ok, Dir} | {error, Reason} when + Drive :: string(), + Dir :: filename(), + Reason :: posix() | badarg. get_cwd(Drive) -> check_and_call(get_cwd, [file_name(Drive)]). --spec set_cwd(Dirname :: name()) -> 'ok' | {'error', posix()}. +-spec set_cwd(Dir) -> ok | {error, Reason} when + Dir :: name(), + Reason :: posix() | badarg. set_cwd(Dirname) -> check_and_call(set_cwd, [file_name(Dirname)]). --spec delete(Name :: name()) -> 'ok' | {'error', posix()}. +-spec delete(Filename) -> ok | {error, Reason} when + Filename :: name(), + Reason :: posix() | badarg. delete(Name) -> check_and_call(delete, [file_name(Name)]). --spec rename(From :: name(), To :: name()) -> 'ok' | {'error', posix()}. +-spec rename(Source, Destination) -> ok | {error, Reason} when + Source :: name(), + Destination :: name(), + Reason :: posix() | badarg. rename(From, To) -> check_and_call(rename, [file_name(From), file_name(To)]). --spec make_dir(Name :: name()) -> 'ok' | {'error', posix()}. +-spec make_dir(Dir) -> ok | {error, Reason} when + Dir :: name(), + Reason :: posix() | badarg. make_dir(Name) -> check_and_call(make_dir, [file_name(Name)]). --spec del_dir(Name :: name()) -> 'ok' | {'error', posix()}. +-spec del_dir(Dir) -> ok | {error, Reason} when + Dir :: name(), + Reason :: posix() | badarg. del_dir(Name) -> check_and_call(del_dir, [file_name(Name)]). --spec read_file_info(Name :: name()) -> {'ok', file_info()} | {'error', posix()}. +-spec read_file_info(Filename) -> {ok, FileInfo} | {error, Reason} when + Filename :: name(), + FileInfo :: file_info(), + Reason :: posix() | badarg. read_file_info(Name) -> check_and_call(read_file_info, [file_name(Name)]). @@ -193,45 +224,66 @@ read_file_info(Name) -> altname(Name) -> check_and_call(altname, [file_name(Name)]). --spec read_link_info(Name :: name()) -> {'ok', file_info()} | {'error', posix()}. +-spec read_link_info(Name) -> {ok, FileInfo} | {error, Reason} when + Name :: name(), + FileInfo :: file_info(), + Reason :: posix() | badarg. read_link_info(Name) -> check_and_call(read_link_info, [file_name(Name)]). --spec read_link(Name :: name()) -> {'ok', filename()} | {'error', posix()}. +-spec read_link(Name) -> {ok, Filename} | {error, Reason} when + Name :: name(), + Filename :: filename(), + Reason :: posix() | badarg. read_link(Name) -> check_and_call(read_link, [file_name(Name)]). --spec write_file_info(Name :: name(), Info :: file_info()) -> - 'ok' | {'error', posix()}. +-spec write_file_info(Filename, FileInfo) -> ok | {error, Reason} when + Filename :: name(), + FileInfo :: file_info(), + Reason :: posix() | badarg. write_file_info(Name, Info = #file_info{}) -> check_and_call(write_file_info, [file_name(Name), Info]). --spec list_dir(Name :: name()) -> {'ok', [filename()]} | {'error', posix()}. +-spec list_dir(Dir) -> {ok, Filenames} | {error, Reason} when + Dir :: name(), + Filenames :: [filename()], + Reason :: posix() | badarg. list_dir(Name) -> check_and_call(list_dir, [file_name(Name)]). --spec read_file(Name :: name()) -> - {'ok', binary()} | {'error', posix() | 'terminated' | 'system_limit'}. +-spec read_file(Filename) -> {ok, Binary} | {error, Reason} when + Filename :: name(), + Binary :: binary(), + Reason :: posix() | badarg | terminated | system_limit. read_file(Name) -> check_and_call(read_file, [file_name(Name)]). --spec make_link(Old :: name(), New :: name()) -> 'ok' | {'error', posix()}. +-spec make_link(Existing, New) -> ok | {error, Reason} when + Existing :: name(), + New :: name(), + Reason :: posix() | badarg. make_link(Old, New) -> check_and_call(make_link, [file_name(Old), file_name(New)]). --spec make_symlink(Old :: name(), New :: name()) -> 'ok' | {'error', posix()}. +-spec make_symlink(Name1, Name2) -> ok | {error, Reason} when + Name1 :: name(), + Name2 :: name(), + Reason :: posix() | badarg. make_symlink(Old, New) -> check_and_call(make_symlink, [file_name(Old), file_name(New)]). --spec write_file(Name :: name(), Bin :: iodata()) -> - 'ok' | {'error', posix() | 'terminated' | 'system_limit'}. +-spec write_file(Filename, Bytes) -> ok | {error, Reason} when + Filename :: name(), + Bytes :: iodata(), + Reason :: posix() | badarg | terminated | system_limit. write_file(Name, Bin) -> check_and_call(write_file, [file_name(Name), make_binary(Bin)]). @@ -240,8 +292,11 @@ write_file(Name, Bin) -> %% when it is time to change file server protocol again. %% Meanwhile, it is implemented here, slightly less efficient. --spec write_file(Name :: name(), Bin :: iodata(), Modes :: [mode()]) -> - 'ok' | {'error', posix()}. +-spec write_file(Filename, Bytes, Modes) -> ok | {error, Reason} when + Filename :: name(), + Bytes :: iodata(), + Modes :: [mode()], + Reason :: posix() | badarg | terminated | system_limit. write_file(Name, Bin, ModeList) when is_list(ModeList) -> case make_binary(Bin) of @@ -295,8 +350,11 @@ raw_write_file_info(Name, #file_info{} = Info) -> %% Contemporary mode specification - list of options --spec open(Name :: name(), Modes :: [mode()]) -> - {'ok', io_device()} | {'error', posix() | 'system_limit'}. +-spec open(Filename, Modes) -> {ok, IoDevice} | {error, Reason} when + Filename :: name(), + Modes :: [mode()], + IoDevice :: io_device(), + Reason :: posix() | badarg | system_limit. open(Item, ModeList) when is_list(ModeList) -> case lists:member(raw, ModeList) of @@ -349,7 +407,9 @@ open(Item, Mode) -> %%% The File argument must be either a Pid or a handle %%% returned from ?PRIM_FILE:open. --spec close(File :: io_device()) -> 'ok' | {'error', posix() | 'terminated'}. +-spec close(IoDevice) -> ok | {error, Reason} when + IoDevice :: io_device(), + Reason :: posix() | badarg | terminated. close(File) when is_pid(File) -> R = file_request(File, close), @@ -367,9 +427,12 @@ close(#file_descriptor{module = Module} = Handle) -> close(_) -> {error, badarg}. --spec advise(File :: io_device(), Offset :: integer(), - Length :: integer(), Advise :: posix_file_advise()) -> - 'ok' | {'error', posix()}. +-spec advise(IoDevice, Offset, Length, Advise) -> ok | {error, Reason} when + IoDevice :: io_device(), + Offset :: integer(), + Length :: integer(), + Advise :: posix_file_advise(), + Reason :: posix() | badarg. advise(File, Offset, Length, Advise) when is_pid(File) -> R = file_request(File, {advise, Offset, Length, Advise}), @@ -379,8 +442,11 @@ advise(#file_descriptor{module = Module} = Handle, Offset, Length, Advise) -> advise(_, _, _, _) -> {error, badarg}. --spec read(File :: io_device() | atom(), Size :: non_neg_integer()) -> - 'eof' | {'ok', [char()] | binary()} | {'error', posix()}. +-spec read(IoDevice, Number) -> {ok, Data} | eof | {error, Reason} when + IoDevice :: io_device() | atom(), + Number :: non_neg_integer(), + Data :: string() | binary(), + Reason :: posix() | badarg | terminated. read(File, Sz) when (is_pid(File) orelse is_atom(File)), is_integer(Sz), Sz >= 0 -> case io:request(File, {get_chars, '', Sz}) of @@ -395,8 +461,10 @@ read(#file_descriptor{module = Module} = Handle, Sz) read(_, _) -> {error, badarg}. --spec read_line(File :: io_device() | atom()) -> - 'eof' | {'ok', [char()] | binary()} | {'error', posix()}. +-spec read_line(IoDevice) -> {ok, Data} | eof | {error, Reason} when + IoDevice :: io_device() | atom(), + Data :: string() | binary(), + Reason :: posix() | badarg | terminated. read_line(File) when (is_pid(File) orelse is_atom(File)) -> case io:request(File, {get_line, ''}) of @@ -410,9 +478,12 @@ read_line(#file_descriptor{module = Module} = Handle) -> read_line(_) -> {error, badarg}. --spec pread(File :: io_device(), - LocationNumbers :: [{location(), non_neg_integer()}]) -> - {'ok', [string() | binary() | 'eof']} | {'error', posix()}. +-spec pread(IoDevice, LocNums) -> {ok, DataL} | eof | {error, Reason} when + IoDevice :: io_device(), + LocNums :: [{Location :: location(), Number :: non_neg_integer()}], + DataL :: [Data], + Data :: string() | binary() | eof, + Reason :: posix() | badarg | terminated. pread(File, L) when is_pid(File), is_list(L) -> pread_int(File, L, []); @@ -435,10 +506,13 @@ pread_int(File, [{At, Sz} | T], R) when is_integer(Sz), Sz >= 0 -> pread_int(_, _, _) -> {error, badarg}. --spec pread(File :: io_device(), - Location :: location(), - Size :: non_neg_integer()) -> - 'eof' | {'ok', string() | binary()} | {'error', posix()}. +-spec pread(IoDevice, Location, Number) -> + {ok, Data} | eof | {error, Reason} when + IoDevice :: io_device(), + Location :: location(), + Number :: non_neg_integer(), + Data :: string() | binary(), + Reason :: posix() | badarg | terminated. pread(File, At, Sz) when is_pid(File), is_integer(Sz), Sz >= 0 -> R = file_request(File, {pread, At, Sz}), @@ -449,8 +523,10 @@ pread(#file_descriptor{module = Module} = Handle, Offs, Sz) pread(_, _, _) -> {error, badarg}. --spec write(File :: io_device() | atom(), Byte :: iodata()) -> - 'ok' | {'error', posix() | 'terminated'}. +-spec write(IoDevice, Bytes) -> ok | {error, Reason} when + IoDevice :: io_device() | atom(), + Bytes :: iodata(), + Reason :: posix() | badarg | terminated. write(File, Bytes) when (is_pid(File) orelse is_atom(File)) -> case make_binary(Bytes) of @@ -464,8 +540,11 @@ write(#file_descriptor{module = Module} = Handle, Bytes) -> write(_, _) -> {error, badarg}. --spec pwrite(File :: io_device(), L :: [{location(), iodata()}]) -> - 'ok' | {'error', {non_neg_integer(), posix()}}. +-spec pwrite(IoDevice, LocBytes) -> ok | {error, {N, Reason}} when + IoDevice :: io_device(), + LocBytes :: [{Location :: location(), Bytes :: iodata()}], + N :: non_neg_integer(), + Reason :: posix() | badarg | terminated. pwrite(File, L) when is_pid(File), is_list(L) -> pwrite_int(File, L, 0); @@ -486,10 +565,11 @@ pwrite_int(File, [{At, Bytes} | T], R) -> pwrite_int(_, _, _) -> {error, badarg}. --spec pwrite(File :: io_device(), - Location :: location(), - Bytes :: iodata()) -> - 'ok' | {'error', posix()}. +-spec pwrite(IoDevice, Location, Bytes) -> ok | {error, Reason} when + IoDevice :: io_device(), + Location :: location(), + Bytes :: iodata(), + Reason :: posix() | badarg | terminated. pwrite(File, At, Bytes) when is_pid(File) -> R = file_request(File, {pwrite, At, Bytes}), @@ -499,7 +579,9 @@ pwrite(#file_descriptor{module = Module} = Handle, Offs, Bytes) -> pwrite(_, _, _) -> {error, badarg}. --spec datasync(File :: io_device()) -> 'ok' | {'error', posix()}. +-spec datasync(IoDevice) -> ok | {error, Reason} when + IoDevice :: io_device(), + Reason :: posix() | badarg | terminated. datasync(File) when is_pid(File) -> R = file_request(File, datasync), @@ -509,7 +591,9 @@ datasync(#file_descriptor{module = Module} = Handle) -> datasync(_) -> {error, badarg}. --spec sync(File :: io_device()) -> 'ok' | {'error', posix()}. +-spec sync(IoDevice) -> ok | {error, Reason} when + IoDevice :: io_device(), + Reason :: posix() | badarg | terminated. sync(File) when is_pid(File) -> R = file_request(File, sync), @@ -519,8 +603,11 @@ sync(#file_descriptor{module = Module} = Handle) -> sync(_) -> {error, badarg}. --spec position(File :: io_device(), Location :: location()) -> - {'ok',integer()} | {'error', posix()}. +-spec position(IoDevice, Location) -> {ok, NewPosition} | {error, Reason} when + IoDevice :: io_device(), + Location :: location(), + NewPosition :: integer(), + Reason :: posix() | badarg | terminated. position(File, At) when is_pid(File) -> R = file_request(File, {position,At}), @@ -530,7 +617,9 @@ position(#file_descriptor{module = Module} = Handle, At) -> position(_, _) -> {error, badarg}. --spec truncate(File :: io_device()) -> 'ok' | {'error', posix()}. +-spec truncate(IoDevice) -> ok | {error, Reason} when + IoDevice :: io_device(), + Reason :: posix() | badarg | terminated. truncate(File) when is_pid(File) -> R = file_request(File, truncate), @@ -540,17 +629,26 @@ truncate(#file_descriptor{module = Module} = Handle) -> truncate(_) -> {error, badarg}. --spec copy(Source :: io_device() | name() | {name(), [mode()]}, - Destination :: io_device() | name() | {name(), [mode()]}) -> - {'ok', non_neg_integer()} | {'error', posix()}. +-spec copy(Source, Destination) -> {ok, BytesCopied} | {error, Reason} when + Source :: io_device() | Filename | {Filename, Modes}, + Destination :: io_device() | Filename | {Filename, Modes}, + Filename :: name(), + Modes :: [mode()], + BytesCopied :: non_neg_integer(), + Reason :: posix() | badarg | terminated. copy(Source, Dest) -> copy_int(Source, Dest, infinity). --spec copy(Source :: io_device() | name() | {name(), [mode()]}, - Destination :: io_device() | name() | {name(), [mode()]}, - Length :: non_neg_integer() | 'infinity') -> - {'ok', non_neg_integer()} | {'error', posix()}. +-spec copy(Source, Destination, ByteCount) -> + {ok, BytesCopied} | {error, Reason} when + Source :: io_device() | Filename | {Filename, Modes}, + Destination :: io_device() | Filename | {Filename, Modes}, + Filename :: name(), + Modes :: [mode()], + ByteCount :: non_neg_integer() | infinity, + BytesCopied :: non_neg_integer(), + Reason :: posix() | badarg | terminated. copy(Source, Dest, Length) when is_integer(Length), Length >= 0; @@ -772,8 +870,11 @@ ipread_s32bu_p32bu_2(File, %%% The following functions, built upon the other interface functions, %%% provide a higher-lever interface to files. --spec consult(File :: name()) -> - {'ok', list()} | {'error', posix() | {integer(), atom(), any()}}. +-spec consult(Filename) -> {ok, Terms} | {error, Reason} when + Filename :: name(), + Terms :: [term()], + Reason :: posix() | badarg | terminated | system_limit + | {Line :: integer(), Mod :: module(), Term :: term()}. consult(File) -> case open(File, [read]) of @@ -785,8 +886,14 @@ consult(File) -> Error end. --spec path_consult(Paths :: [name()], File :: name()) -> - {'ok', list(), filename()} | {'error', posix() | {integer(), atom(), any()}}. +-spec path_consult(Path, Filename) -> {ok, Terms, FullName} | {error, Reason} when + Path :: [Dir], + Dir :: name(), + Filename :: name(), + Terms :: [term()], + FullName :: filename(), + Reason :: posix() | badarg | terminated | system_limit + | {Line :: integer(), Mod :: module(), Term :: term()}. path_consult(Path, File) -> case path_open(Path, File, [read]) of @@ -803,13 +910,19 @@ path_consult(Path, File) -> E2 end. --spec eval(File :: name()) -> 'ok' | {'error', posix()}. +-spec eval(Filename) -> ok | {error, Reason} when + Filename :: name(), + Reason :: posix() | badarg | terminated | system_limit + | {Line :: integer(), Mod :: module(), Term :: term()}. eval(File) -> eval(File, erl_eval:new_bindings()). --spec eval(File :: name(), Bindings :: bindings()) -> - 'ok' | {'error', posix()}. +-spec eval(Filename, Bindings) -> ok | {error, Reason} when + Filename :: name(), + Bindings :: bindings(), + Reason :: posix() | badarg | terminated | system_limit + | {Line :: integer(), Mod :: module(), Term :: term()}. eval(File, Bs) -> case open(File, [read]) of @@ -821,14 +934,24 @@ eval(File, Bs) -> Error end. --spec path_eval(Paths :: [name()], File :: name()) -> - {'ok', filename()} | {'error', posix() | {integer(), atom(), any()}}. +-spec path_eval(Path, Filename) -> {ok, FullName} | {error, Reason} when + Path :: [Dir :: name()], + Filename :: name(), + FullName :: filename(), + Reason :: posix() | badarg | terminated | system_limit + | {Line :: integer(), Mod :: module(), Term :: term()}. path_eval(Path, File) -> path_eval(Path, File, erl_eval:new_bindings()). --spec path_eval(Paths :: [name()], File :: name(), Bindings :: bindings()) -> - {'ok', filename()} | {'error', posix() | {integer(), atom(), any()}}. +-spec path_eval(Path, Filename, Bindings) -> + {ok, FullName} | {error, Reason} when + Path :: [Dir :: name()], + Filename :: name(), + Bindings :: bindings(), + FullName :: filename(), + Reason :: posix() | badarg | terminated | system_limit + | {Line :: integer(), Mod :: module(), Term :: term()}. path_eval(Path, File, Bs) -> case path_open(Path, File, [read]) of @@ -845,14 +968,21 @@ path_eval(Path, File, Bs) -> E2 end. --spec script(File :: name()) -> - {'ok', any()} | {'error', posix() | {integer(), atom(), any()}}. +-spec script(Filename) -> {ok, Value} | {error, Reason} when + Filename :: name(), + Value :: term(), + Reason :: posix() | badarg | terminated | system_limit + | {Line :: integer(), Mod :: module(), Term :: term()}. script(File) -> script(File, erl_eval:new_bindings()). --spec script(File :: name(), Bindings :: bindings()) -> - {'ok', any()} | {'error', posix() | {integer(), atom(), any()}}. +-spec script(Filename, Bindings) -> {ok, Value} | {error, Reason} when + Filename :: name(), + Bindings :: bindings(), + Value :: term(), + Reason :: posix() | badarg | terminated | system_limit + | {Line :: integer(), Mod :: module(), Term :: term()}. script(File, Bs) -> case open(File, [read]) of @@ -864,16 +994,27 @@ script(File, Bs) -> Error end. --spec path_script/2 :: (Paths :: [name()], File :: name()) -> - {'ok', term(), filename()} | {'error', posix() | {integer(), atom(), _}}. +-spec path_script(Path, Filename) -> + {ok, Value, FullName} | {error, Reason} when + Path :: [Dir :: name()], + Filename :: name(), + Value :: term(), + FullName :: filename(), + Reason :: posix() | badarg | terminated | system_limit + | {Line :: integer(), Mod :: module(), Term :: term()}. path_script(Path, File) -> path_script(Path, File, erl_eval:new_bindings()). --spec path_script(Paths :: [name()], - File :: name(), - Bindings :: bindings()) -> - {'ok', term(), filename()} | {'error', posix() | {integer(), atom(), _}}. +-spec path_script(Path, Filename, Bindings) -> + {ok, Value, FullName} | {error, Reason} when + Path :: [Dir :: name()], + Filename :: name(), + Bindings :: bindings(), + Value :: term(), + FullName :: filename(), + Reason :: posix() | badarg | terminated | system_limit + | {Line :: integer(), Mod :: module(), Term :: term()}. path_script(Path, File, Bs) -> case path_open(Path, File, [read]) of @@ -898,8 +1039,14 @@ path_script(Path, File, Bs) -> %% Searches the Paths for file Filename which can be opened with Mode. %% The path list is ignored if Filename contains an absolute path. --spec path_open(Paths :: [name()], Name :: name(), Modes :: [mode()]) -> - {'ok', io_device(), filename()} | {'error', posix()}. +-spec path_open(Path, Filename, Modes) -> + {ok, IoDevice, FullName} | {error, Reason} when + Path :: [Dir :: name()], + Filename :: name(), + Modes :: [mode()], + IoDevice :: io_device(), + FullName :: filename(), + Reason :: posix() | badarg | system_limit. path_open(PathList, Name, Mode) -> case file_name(Name) of @@ -919,47 +1066,57 @@ path_open(PathList, Name, Mode) -> end end. --spec change_mode(Name :: name(), Mode :: integer()) -> - 'ok' | {'error', posix()}. +-spec change_mode(Filename, Mode) -> ok | {error, Reason} when + Filename :: name(), + Mode :: integer(), + Reason :: posix() | badarg. change_mode(Name, Mode) when is_integer(Mode) -> write_file_info(Name, #file_info{mode=Mode}). --spec change_owner(Name :: name(), OwnerId :: integer()) -> - 'ok' | {'error', posix()}. +-spec change_owner(Filename, Uid) -> ok | {error, Reason} when + Filename :: name(), + Uid :: integer(), + Reason :: posix() | badarg. change_owner(Name, OwnerId) when is_integer(OwnerId) -> write_file_info(Name, #file_info{uid=OwnerId}). --spec change_owner(Name :: name(), - OwnerId :: integer(), - GroupId :: integer()) -> - 'ok' | {'error', posix()}. +-spec change_owner(Filename, Uid, Gid) -> ok | {error, Reason} when + Filename :: name(), + Uid :: integer(), + Gid :: integer(), + Reason :: posix() | badarg. change_owner(Name, OwnerId, GroupId) when is_integer(OwnerId), is_integer(GroupId) -> write_file_info(Name, #file_info{uid=OwnerId, gid=GroupId}). --spec change_group(Name :: name(), GroupId :: integer()) -> - 'ok' | {'error', posix()}. +-spec change_group(Filename, Gid) -> ok | {error, Reason} when + Filename :: name(), + Gid :: integer(), + Reason :: posix() | badarg. change_group(Name, GroupId) when is_integer(GroupId) -> write_file_info(Name, #file_info{gid=GroupId}). --spec change_time(Name :: name(), Time :: date_time()) -> - 'ok' | {'error', posix()}. +-spec change_time(Filename, Mtime) -> ok | {error, Reason} when + Filename :: name(), + Mtime :: date_time(), + Reason :: posix() | badarg. change_time(Name, Time) when is_tuple(Time) -> write_file_info(Name, #file_info{mtime=Time}). --spec change_time(Name :: name(), - ATime :: date_time(), - MTime :: date_time()) -> - 'ok' | {'error', posix()}. +-spec change_time(Filename, Atime, Mtime) -> ok | {error, Reason} when + Filename :: name(), + Atime :: date_time(), + Mtime :: date_time(), + Reason :: posix() | badarg. change_time(Name, Atime, Mtime) when is_tuple(Atime), is_tuple(Mtime) -> diff --git a/lib/kernel/src/gen_sctp.erl b/lib/kernel/src/gen_sctp.erl index cccfa75005..004f03f231 100644 --- a/lib/kernel/src/gen_sctp.erl +++ b/lib/kernel/src/gen_sctp.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2007-2010. All Rights Reserved. +%% Copyright Ericsson AB 2007-2011. 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 @@ -33,11 +33,57 @@ -export([error_string/1]). -export([controlling_process/2]). - +-opaque assoc_id() :: term(). +-type hostname() :: inet:hostname(). +-type ip_address() :: inet:ip_address(). +-type port_number() :: 0..65535. +-type posix() :: inet:posix(). +-type sctp_option() :: + {mode, list | binary} | list | binary + | {active, true | false | once} + | {buffer, non_neg_integer()} + | {tos, integer()} + | {priority, integer()} + | {dontroute, boolean()} + | {reuseaddr, boolean()} + | {linger, {boolean(), non_neg_integer()}} + | {sndbuf, non_neg_integer()} + | {recbuf, non_neg_integer()} + | {sctp_rtoinfo, #sctp_rtoinfo{}} + | {sctp_associnfo, #sctp_assocparams{}} + | {sctp_initmsg, #sctp_initmsg{}} + | {sctp_autoclose, timeout()} + | {sctp_nodelay, boolean()} + | {sctp_disable_fragments, boolean()} + | {sctp_i_want_mapped_v4_addr, boolean()} + | {sctp_maxseg, non_neg_integer()} + | {sctp_primary_addr, #sctp_prim{}} + | {sctp_set_peer_primary_addr, #sctp_setpeerprim{}} + | {sctp_adaptation_layer, #sctp_setadaptation{}} + | {sctp_peer_addr_params, #sctp_paddrparams{}} + | {sctp_default_send_param, #sctp_sndrcvinfo{}} + | {sctp_events, #sctp_event_subscribe{}} + | {sctp_delayed_ack_time, #sctp_assoc_value{}} + | {sctp_status, #sctp_status{}} + | {sctp_get_peer_addr_info, #sctp_paddrinfo{}}. +-opaque sctp_socket() :: port(). + +-spec open() -> {ok, Socket} | {error, posix()} when + Socket :: sctp_socket(). open() -> open([]). +-spec open(Port) -> {ok, Socket} | {error, posix()} when + Port :: port_number(), + Socket :: sctp_socket(); + (Opts) -> {ok, Socket} | {error, posix()} when + Opts :: [Opt], + Opt :: {ip,IP} | {ifaddr,IP} | {port,Port} | sctp_option(), + IP :: ip_address() | any | loopback, + Port :: port_number(), + Socket :: sctp_socket(). + open(Opts) when is_list(Opts) -> Mod = mod(Opts, undefined), case Mod:open(Opts) of @@ -52,11 +98,21 @@ open(Port) when is_integer(Port) -> open(X) -> erlang:error(badarg, [X]). +-spec open(Port, Opts) -> {ok, Socket} | {error, posix()} when + Opts :: [Opt], + Opt :: {ip,IP} | {ifaddr,IP} | {port,Port} | sctp_option(), + IP :: ip_address() | any | loopback, + Port :: port_number(), + Socket :: sctp_socket(). + open(Port, Opts) when is_integer(Port), is_list(Opts) -> open([{port,Port}|Opts]); open(Port, Opts) -> erlang:error(badarg, [Port,Opts]). +-spec close(Socket) -> ok | {error, posix()} when + Socket :: sctp_socket(). + close(S) when is_port(S) -> case inet_db:lookup_socket(S) of {ok,Mod} -> @@ -68,6 +124,11 @@ close(S) -> +-spec listen(Socket, IsServer) -> ok | {error, Reason} when + Socket :: sctp_socket(), + IsServer :: boolean(), + Reason :: term(). + listen(S, Flag) when is_port(S), is_boolean(Flag) -> case inet_db:lookup_socket(S) of {ok,Mod} -> @@ -77,9 +138,25 @@ listen(S, Flag) when is_port(S), is_boolean(Flag) -> listen(S, Flag) -> erlang:error(badarg, [S,Flag]). +-spec connect(Socket, Addr, Port, Opts) -> {ok, Assoc} | {error, posix()} when + Socket :: sctp_socket(), + Addr :: ip_address() | hostname(), + Port :: port_number(), + Opts :: [Opt :: sctp_option()], + Assoc :: #sctp_assoc_change{}. + connect(S, Addr, Port, Opts) -> connect(S, Addr, Port, Opts, infinity). +-spec connect(Socket, Addr, Port, Opts, Timeout) -> + {ok, Assoc} | {error, posix()} when + Socket :: sctp_socket(), + Addr :: ip_address() | hostname(), + Port :: port_number(), + Opts :: [Opt :: sctp_option()], + Timeout :: timeout(), + Assoc :: #sctp_assoc_change{}. + connect(S, Addr, Port, Opts, Timeout) -> case do_connect(S, Addr, Port, Opts, Timeout, true) of badarg -> @@ -88,9 +165,24 @@ connect(S, Addr, Port, Opts, Timeout) -> Result end. +-spec connect_init(Socket, Addr, Port, Opts) -> + ok | {error, posix()} when + Socket :: sctp_socket(), + Addr :: ip_address() | hostname(), + Port :: port_number(), + Opts :: [sctp_option()]. + connect_init(S, Addr, Port, Opts) -> connect_init(S, Addr, Port, Opts, infinity). +-spec connect_init(Socket, Addr, Port, Opts, Timeout) -> + ok | {error, posix()} when + Socket :: sctp_socket(), + Addr :: ip_address() | hostname(), + Port :: port_number(), + Opts :: [sctp_option()], + Timeout :: timeout(). + connect_init(S, Addr, Port, Opts, Timeout) -> case do_connect(S, Addr, Port, Opts, Timeout, false) of badarg -> @@ -130,12 +222,20 @@ do_connect(_S, _Addr, _Port, _Opts, _Timeout, _ConnWait) -> badarg. +-spec eof(Socket, Assoc) -> ok | {error, Reason} when + Socket :: sctp_socket(), + Assoc :: #sctp_assoc_change{}, + Reason :: term(). eof(S, #sctp_assoc_change{assoc_id=AssocId}) when is_port(S) -> eof_or_abort(S, AssocId, eof); eof(S, Assoc) -> erlang:error(badarg, [S,Assoc]). +-spec abort(Socket, Assoc) -> ok | {error, posix()} when + Socket :: sctp_socket(), + Assoc :: #sctp_assoc_change{}. + abort(S, #sctp_assoc_change{assoc_id=AssocId}) when is_port(S) -> eof_or_abort(S, AssocId, abort); abort(S, Assoc) -> @@ -151,6 +251,11 @@ eof_or_abort(S, AssocId, Action) -> end. +-spec send(Socket, SndRcvInfo, Data) -> ok | {error, Reason} when + Socket :: sctp_socket(), + SndRcvInfo :: #sctp_sndrcvinfo{}, + Data :: binary | iolist(), + Reason :: term(). %% Full-featured send. Rarely needed. send(S, #sctp_sndrcvinfo{}=SRI, Data) when is_port(S) -> @@ -162,6 +267,13 @@ send(S, #sctp_sndrcvinfo{}=SRI, Data) when is_port(S) -> send(S, SRI, Data) -> erlang:error(badarg, [S,SRI,Data]). +-spec send(Socket, Assoc, Stream, Data) -> ok | {error, Reason} when + Socket :: sctp_socket(), + Assoc :: #sctp_assoc_change{} | assoc_id(), + Stream :: integer(), + Data :: binary | iolist(), + Reason :: term(). + send(S, #sctp_assoc_change{assoc_id=AssocId}, Stream, Data) when is_port(S), is_integer(Stream) -> case inet_db:lookup_socket(S) of @@ -179,9 +291,36 @@ send(S, AssocId, Stream, Data) send(S, AssocChange, Stream, Data) -> erlang:error(badarg, [S,AssocChange,Stream,Data]). +-spec recv(Socket) -> {ok, {FromIP, FromPort, AncData, Data}} + | {error, Reason} when + Socket :: sctp_socket(), + FromIP :: ip_address(), + FromPort :: port_number(), + AncData :: [#sctp_sndrcvinfo{}], + Data :: binary() | string() | #sctp_sndrcvinfo{} + | #sctp_assoc_change{} | #sctp_paddr_change{} + | #sctp_adaptation_event{}, + Reason :: posix() | #sctp_send_failed{} | #sctp_paddr_change{} + | #sctp_pdapi_event{} | #sctp_remote_error{} + | #sctp_shutdown_event{}. + recv(S) -> recv(S, infinity). +-spec recv(Socket, Timeout) -> {ok, {FromIP, FromPort, AncData, Data}} + | {error, Reason} when + Socket :: sctp_socket(), + Timeout :: timeout(), + FromIP :: ip_address(), + FromPort :: port_number(), + AncData :: [#sctp_sndrcvinfo{}], + Data :: binary() | string() | #sctp_sndrcvinfo{} + | #sctp_assoc_change{} | #sctp_paddr_change{} + | #sctp_adaptation_event{}, + Reason :: posix() | #sctp_send_failed{} | #sctp_paddr_change{} + | #sctp_pdapi_event{} | #sctp_remote_error{} + | #sctp_shutdown_event{}. + recv(S, Timeout) when is_port(S) -> case inet_db:lookup_socket(S) of {ok,Mod} -> @@ -192,6 +331,8 @@ recv(S, Timeout) -> erlang:error(badarg, [S,Timeout]). +-spec error_string(ErrorNumber) -> ok | string() | unknown_error when + ErrorNumber :: integer(). error_string(0) -> ok; @@ -224,6 +365,9 @@ error_string(X) -> erlang:error(badarg, [X]). +-spec controlling_process(Socket, Pid) -> ok when + Socket :: sctp_socket(), + Pid :: pid(). controlling_process(S, Pid) when is_port(S), is_pid(Pid) -> inet:udp_controlling_process(S, Pid); diff --git a/lib/kernel/src/gen_tcp.erl b/lib/kernel/src/gen_tcp.erl index 16a87d71b6..bee61ca84a 100644 --- a/lib/kernel/src/gen_tcp.erl +++ b/lib/kernel/src/gen_tcp.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2010. All Rights Reserved. +%% Copyright Ericsson AB 1997-2011. 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 @@ -28,12 +28,35 @@ -include("inet_int.hrl"). +-type hostname() :: inet:hostname(). +-type ip_address() :: inet:ip_address(). +-type port_number() :: 0..65535. +-type posix() :: inet:posix(). +-type socket() :: port(). + %% %% Connect a socket %% + +-spec connect(Address, Port, Options) -> {ok, Socket} | {error, Reason} when + Address :: ip_address() | hostname(), + Port :: port_number(), + Options :: [Opt :: term()], + Socket :: socket(), + Reason :: posix(). + connect(Address, Port, Opts) -> connect(Address,Port,Opts,infinity). +-spec connect(Address, Port, Options, Timeout) -> + {ok, Socket} | {error, Reason} when + Address :: ip_address() | hostname(), + Port :: port_number(), + Options :: [Opt :: term()], + Timeout :: timeout(), + Socket :: socket(), + Reason :: posix(). + connect(Address, Port, Opts, Time) -> Timer = inet:start_timer(Time), Res = (catch connect1(Address,Port,Opts,Timer)), @@ -72,6 +95,13 @@ try_connect([], _Port, _Opts, _Timer, _Mod, Err) -> %% %% Listen on a tcp port %% + +-spec listen(Port, Options) -> {ok, ListenSocket} | {error, Reason} when + Port :: port_number(), + Options :: [Opt :: term()], + ListenSocket :: socket(), + Reason :: posix(). + listen(Port, Opts) -> Mod = mod(Opts, undefined), case Mod:getserv(Port) of @@ -85,6 +115,12 @@ listen(Port, Opts) -> %% %% Generic tcp accept %% + +-spec accept(ListenSocket) -> {ok, Socket} | {error, Reason} when + ListenSocket :: socket(), + Socket :: socket(), + Reason :: closed | timeout | posix(). + accept(S) -> case inet_db:lookup_socket(S) of {ok, Mod} -> @@ -93,6 +129,12 @@ accept(S) -> Error end. +-spec accept(ListenSocket, Timeout) -> {ok, Socket} | {error, Reason} when + ListenSocket :: socket(), + Timeout :: timeout(), + Socket :: socket(), + Reason :: closed | timeout | posix(). + accept(S, Time) when is_port(S) -> case inet_db:lookup_socket(S) of {ok, Mod} -> @@ -104,6 +146,12 @@ accept(S, Time) when is_port(S) -> %% %% Generic tcp shutdown %% + +-spec shutdown(Socket, How) -> ok | {error, Reason} when + Socket :: socket(), + How :: read | write | read_write, + Reason :: posix(). + shutdown(S, How) when is_port(S) -> case inet_db:lookup_socket(S) of {ok, Mod} -> @@ -115,12 +163,22 @@ shutdown(S, How) when is_port(S) -> %% %% Close %% + +-spec close(Socket) -> ok when + Socket :: socket(). + close(S) -> inet:tcp_close(S). %% %% Send %% + +-spec send(Socket, Packet) -> ok | {error, Reason} when + Socket :: socket(), + Packet :: string() | binary(), + Reason :: posix(). + send(S, Packet) when is_port(S) -> case inet_db:lookup_socket(S) of {ok, Mod} -> @@ -132,6 +190,14 @@ send(S, Packet) when is_port(S) -> %% %% Receive data from a socket (passive mode) %% + +-spec recv(Socket, Length) -> {ok, Packet} | {error, Reason} when + Socket :: socket(), + Length :: non_neg_integer(), + Packet :: string() | binary() | HttpPacket, + Reason :: closed | posix(), + HttpPacket :: term(). + recv(S, Length) when is_port(S) -> case inet_db:lookup_socket(S) of {ok, Mod} -> @@ -140,6 +206,14 @@ recv(S, Length) when is_port(S) -> Error end. +-spec recv(Socket, Length, Timeout) -> {ok, Packet} | {error, Reason} when + Socket :: socket(), + Length :: non_neg_integer(), + Timeout :: timeout(), + Packet :: string() | binary() | HttpPacket, + Reason :: closed | posix(), + HttpPacket :: term(). + recv(S, Length, Time) when is_port(S) -> case inet_db:lookup_socket(S) of {ok, Mod} -> @@ -159,6 +233,12 @@ unrecv(S, Data) when is_port(S) -> %% %% Set controlling process %% + +-spec controlling_process(Socket, Pid) -> ok | {error, Reason} when + Socket :: socket(), + Pid :: pid(), + Reason :: closed | not_owner | posix(). + controlling_process(S, NewOwner) -> case inet_db:lookup_socket(S) of {ok, _Mod} -> % Just check that this is an open socket diff --git a/lib/kernel/src/gen_udp.erl b/lib/kernel/src/gen_udp.erl index 99020c7b6c..7d14615c04 100644 --- a/lib/kernel/src/gen_udp.erl +++ b/lib/kernel/src/gen_udp.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2010. All Rights Reserved. +%% Copyright Ericsson AB 1997-2011. 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 @@ -25,17 +25,44 @@ -include("inet_int.hrl"). +-type hostname() :: inet:hostname(). +-type ip_address() :: inet:ip_address(). +-type port_number() :: 0..65535. +-type posix() :: inet:posix(). +-type socket() :: port(). + +-spec open(Port) -> {ok, Socket} | {error, Reason} when + Port :: port_number(), + Socket :: socket(), + Reason :: posix(). + open(Port) -> open(Port, []). +-spec open(Port, Opts) -> {ok, Socket} | {error, Reason} when + Port :: port_number(), + Opts :: [Opt :: term()], + Socket :: socket(), + Reason :: posix(). + open(Port, Opts) -> Mod = mod(Opts, undefined), {ok,UP} = Mod:getserv(Port), Mod:open(UP, Opts). +-spec close(Socket) -> ok when + Socket :: socket(). + close(S) -> inet:udp_close(S). +-spec send(Socket, Address, Port, Packet) -> ok | {error, Reason} when + Socket :: socket(), + Address :: ip_address() | hostname(), + Port :: port_number(), + Packet :: string() | binary(), + Reason :: not_owner | posix(). + send(S, Address, Port, Packet) when is_port(S) -> case inet_db:lookup_socket(S) of {ok, Mod} -> @@ -61,6 +88,15 @@ send(S, Packet) when is_port(S) -> Error end. +-spec recv(Socket, Length) -> + {ok, {Address, Port, Packet}} | {error, Reason} when + Socket :: socket(), + Length :: non_neg_integer(), + Address :: ip_address(), + Port :: port_number(), + Packet :: string() | binary(), + Reason :: not_owner | posix(). + recv(S,Len) when is_port(S), is_integer(Len) -> case inet_db:lookup_socket(S) of {ok, Mod} -> @@ -69,6 +105,16 @@ recv(S,Len) when is_port(S), is_integer(Len) -> Error end. +-spec recv(Socket, Length, Timeout) -> + {ok, {Address, Port, Packet}} | {error, Reason} when + Socket :: socket(), + Length :: non_neg_integer(), + Timeout :: timeout(), + Address :: ip_address(), + Port :: port_number(), + Packet :: string() | binary(), + Reason :: not_owner | posix(). + recv(S,Len,Time) when is_port(S) -> case inet_db:lookup_socket(S) of {ok, Mod} -> @@ -90,6 +136,10 @@ connect(S, Address, Port) when is_port(S) -> Error end. +-spec controlling_process(Socket, Pid) -> ok when + Socket :: socket(), + Pid :: pid(). + controlling_process(S, NewOwner) -> inet:udp_controlling_process(S, NewOwner). diff --git a/lib/kernel/src/global.erl b/lib/kernel/src/global.erl index 6343acd000..7d15f8bf83 100644 --- a/lib/kernel/src/global.erl +++ b/lib/kernel/src/global.erl @@ -166,7 +166,7 @@ start_link() -> stop() -> gen_server:call(global_name_server, stop, infinity). --spec sync() -> 'ok' | {'error', term()}. +-spec sync() -> 'ok' | {'error', Reason :: term()}. sync() -> case check_sync_nodes() of {error, _} = Error -> @@ -175,7 +175,7 @@ sync() -> gen_server:call(global_name_server, {sync, SyncNodes}, infinity) end. --spec sync([node()]) -> 'ok' | {'error', term()}. +-spec sync([node()]) -> 'ok' | {'error', Reason :: term()}. sync(Nodes) -> case check_sync_nodes(Nodes) of {error, _} = Error -> @@ -184,7 +184,10 @@ sync(Nodes) -> gen_server:call(global_name_server, {sync, SyncNodes}, infinity) end. --spec send(term(), term()) -> pid(). +-spec send(Name, Msg) -> Pid when + Name :: term(), + Msg :: term(), + Pid :: pid(). send(Name, Msg) -> case whereis_name(Name) of Pid when is_pid(Pid) -> @@ -195,7 +198,8 @@ send(Name, Msg) -> end. %% See OTP-3737. --spec whereis_name(term()) -> pid() | 'undefined'. +-spec whereis_name(Name) -> pid() | 'undefined' when + Name :: term(). whereis_name(Name) -> where(Name). @@ -219,13 +223,19 @@ node_disconnected(Node) -> %% undefined which one of them is used. %% Method blocks the name registration, but does not affect global locking. %%----------------------------------------------------------------- --spec register_name(term(), pid()) -> 'yes' | 'no'. +-spec register_name(Name, Pid) -> 'yes' | 'no' when + Name :: term(), + Pid :: pid(). register_name(Name, Pid) when is_pid(Pid) -> register_name(Name, Pid, fun random_exit_name/3). --type method() :: fun((term(), pid(), pid()) -> pid() | 'none'). +-type method() :: fun((Name :: term(), Pid :: pid(), Pid2 :: pid()) -> + pid() | 'none'). --spec register_name(term(), pid(), method()) -> 'yes' | 'no'. +-spec register_name(Name, Pid, Resolve) -> 'yes' | 'no' when + Name :: term(), + Pid :: pid(), + Resolve :: method(). register_name(Name, Pid, Method) when is_pid(Pid) -> Fun = fun(Nodes) -> case (where(Name) =:= undefined) andalso check_dupname(Name, Pid) of @@ -257,7 +267,8 @@ check_dupname(Name, Pid) -> end end. --spec unregister_name(term()) -> _. +-spec unregister_name(Name) -> _ when + Name :: term(). unregister_name(Name) -> case where(Name) of undefined -> @@ -273,11 +284,16 @@ unregister_name(Name) -> gen_server:call(global_name_server, {registrar, Fun}, infinity) end. --spec re_register_name(term(), pid()) -> _. +-spec re_register_name(Name, Pid) -> _ when + Name :: term(), + Pid :: pid(). re_register_name(Name, Pid) when is_pid(Pid) -> re_register_name(Name, Pid, fun random_exit_name/3). --spec re_register_name(term(), pid(), method()) -> _. +-spec re_register_name(Name, Pid, Resolve) -> _ when + Name :: term(), + Pid :: pid(), + Resolve :: method(). re_register_name(Name, Pid, Method) when is_pid(Pid) -> Fun = fun(Nodes) -> gen_server:multi_call(Nodes, @@ -288,7 +304,8 @@ re_register_name(Name, Pid, Method) when is_pid(Pid) -> ?trace({re_register_name, self(), Name, Pid, Method}), gen_server:call(global_name_server, {registrar, Fun}, infinity). --spec registered_names() -> [term()]. +-spec registered_names() -> [Name] when + Name :: term(). registered_names() -> MS = ets:fun2ms(fun({Name,_Pid,_M,_RP,_R}) -> Name end), ets:select(global_names, MS). @@ -329,19 +346,25 @@ register_name_external(Name, Pid, Method) when is_pid(Pid) -> unregister_name_external(Name) -> unregister_name(Name). --type id() :: {term(), term()}. +-type id() :: {ResourceId :: term(), LockRequesterId :: term()}. --spec set_lock(id()) -> boolean(). +-spec set_lock(Id) -> boolean() when + Id :: id(). set_lock(Id) -> set_lock(Id, [node() | nodes()], infinity, 1). -type retries() :: non_neg_integer() | 'infinity'. --spec set_lock(id(), [node()]) -> boolean(). +-spec set_lock(Id, Nodes) -> boolean() when + Id :: id(), + Nodes :: [node()]. set_lock(Id, Nodes) -> set_lock(Id, Nodes, infinity, 1). --spec set_lock(id(), [node()], retries()) -> boolean(). +-spec set_lock(Id, Nodes, Retries) -> boolean() when + Id :: id(), + Nodes :: [node()], + Retries :: retries(). set_lock(Id, Nodes, Retries) when is_integer(Retries), Retries >= 0 -> set_lock(Id, Nodes, Retries, 1); set_lock(Id, Nodes, infinity) -> @@ -363,11 +386,14 @@ set_lock({_ResourceId, _LockRequesterId} = Id, Nodes, Retries, Times) -> set_lock(Id, Nodes, dec(Retries), Times+1) end. --spec del_lock(id()) -> 'true'. +-spec del_lock(Id) -> 'true' when + Id :: id(). del_lock(Id) -> del_lock(Id, [node() | nodes()]). --spec del_lock(id(), [node()]) -> 'true'. +-spec del_lock(Id, Nodes) -> 'true' when + Id :: id(), + Nodes :: [node()]. del_lock({_ResourceId, _LockRequesterId} = Id, Nodes) -> ?trace({del_lock, {me,self()}, Id, {nodes,Nodes}}), gen_server:multi_call(Nodes, global_name_server, {del_lock, Id}), @@ -375,13 +401,25 @@ del_lock({_ResourceId, _LockRequesterId} = Id, Nodes) -> -type trans_fun() :: function() | {module(), atom()}. --spec trans(id(), trans_fun()) -> term(). +-spec trans(Id, Fun) -> Res | aborted when + Id :: id(), + Fun :: trans_fun(), + Res :: term(). trans(Id, Fun) -> trans(Id, Fun, [node() | nodes()], infinity). --spec trans(id(), trans_fun(), [node()]) -> term(). +-spec trans(Id, Fun, Nodes) -> Res | aborted when + Id :: id(), + Fun :: trans_fun(), + Nodes :: [node()], + Res :: term(). trans(Id, Fun, Nodes) -> trans(Id, Fun, Nodes, infinity). --spec trans(id(), trans_fun(), [node()], retries()) -> term(). +-spec trans(Id, Fun, Nodes, Retries) -> Res | aborted when + Id :: id(), + Fun :: trans_fun(), + Nodes :: [node()], + Retries :: retries(), + Res :: term(). trans(Id, Fun, Nodes, Retries) -> case set_lock(Id, Nodes, Retries) of true -> @@ -1928,7 +1966,10 @@ resolve_it(Method, Name, Pid1, Pid2) -> minmax(P1,P2) -> if node(P1) < node(P2) -> {P1, P2}; true -> {P2, P1} end. --spec random_exit_name(term(), pid(), pid()) -> pid(). +-spec random_exit_name(Name, Pid1, Pid2) -> 'none' when + Name :: term(), + Pid1 :: pid(), + Pid2 :: pid(). random_exit_name(Name, Pid, Pid2) -> {Min, Max} = minmax(Pid, Pid2), error_logger:info_msg("global: Name conflict terminating ~w\n", @@ -1936,12 +1977,19 @@ random_exit_name(Name, Pid, Pid2) -> exit(Max, kill), Min. +-spec random_notify_name(Name, Pid1, Pid2) -> 'none' when + Name :: term(), + Pid1 :: pid(), + Pid2 :: pid(). random_notify_name(Name, Pid, Pid2) -> {Min, Max} = minmax(Pid, Pid2), Max ! {global_name_conflict, Name}, Min. --spec notify_all_name(term(), pid(), pid()) -> 'none'. +-spec notify_all_name(Name, Pid1, Pid2) -> 'none' when + Name :: term(), + Pid1 :: pid(), + Pid2 :: pid(). notify_all_name(Name, Pid, Pid2) -> Pid ! {global_name_conflict, Name, Pid2}, Pid2 ! {global_name_conflict, Name, Pid}, diff --git a/lib/kernel/src/global_group.erl b/lib/kernel/src/global_group.erl index 7e141ac5c7..025a9b8a5b 100644 --- a/lib/kernel/src/global_group.erl +++ b/lib/kernel/src/global_group.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1998-2009. All Rights Reserved. +%% Copyright Ericsson AB 1998-2011. 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 @@ -62,9 +62,10 @@ -type sync_state() :: 'no_conf' | 'synced'. -type group_name() :: atom(). --type group_tuple() :: {group_name(), [node()]} - | {group_name(), publish_type(), [node()]}. - +-type group_tuple() :: {GroupName :: group_name(), [node()]} + | {GroupName :: group_name(), + PublishType :: publish_type(), + [node()]}. %%%==================================================================================== %%% The state of the global_group process @@ -97,11 +98,14 @@ %%% External exported %%%==================================================================================== --spec global_groups() -> {group_name(), [group_name()]} | 'undefined'. +-spec global_groups() -> {GroupName, GroupNames} | undefined when + GroupName :: group_name(), + GroupNames :: [GroupName]. global_groups() -> request(global_groups). --spec monitor_nodes(boolean()) -> 'ok'. +-spec monitor_nodes(Flag) -> 'ok' when + Flag :: boolean(). monitor_nodes(Flag) -> case Flag of true -> request({monitor_nodes, Flag}); @@ -109,30 +113,41 @@ monitor_nodes(Flag) -> _ -> {error, not_boolean} end. --spec own_nodes() -> [node()]. +-spec own_nodes() -> Nodes when + Nodes :: [Node :: node()]. own_nodes() -> request(own_nodes). -type name() :: atom(). -type where() :: {'node', node()} | {'group', group_name()}. --spec registered_names(where()) -> [name()]. +-spec registered_names(Where) -> Names when + Where :: where(), + Names :: [Name :: name()]. registered_names(Arg) -> request({registered_names, Arg}). --spec send(name(), term()) -> pid() | {'badarg', {name(), term()}}. +-spec send(Name, Msg) -> pid() | {'badarg', {Name, Msg}} when + Name :: name(), + Msg :: term(). send(Name, Msg) -> request({send, Name, Msg}). --spec send(where(), name(), term()) -> pid() | {'badarg', {name(), term()}}. +-spec send(Where, Name, Msg) -> pid() | {'badarg', {Name, Msg}} when + Where :: where(), + Name :: name(), + Msg :: term(). send(Group, Name, Msg) -> request({send, Group, Name, Msg}). --spec whereis_name(name()) -> pid() | 'undefined'. +-spec whereis_name(Name) -> pid() | 'undefined' when + Name :: name(). whereis_name(Name) -> request({whereis_name, Name}). --spec whereis_name(where(), name()) -> pid() | 'undefined'. +-spec whereis_name(Where, Name) -> pid() | 'undefined' when + Where :: where(), + Name :: name(). whereis_name(Group, Name) -> request({whereis_name, Group, Name}). @@ -155,14 +170,14 @@ ng_add_check(Node, OthersNG) -> ng_add_check(Node, PubType, OthersNG) -> request({ng_add_check, Node, PubType, OthersNG}). --type info_item() :: {'state', sync_state()} - | {'own_group_name', group_name()} - | {'own_group_nodes', [node()]} - | {'synched_nodes', [node()]} - | {'sync_error', [node()]} - | {'no_contact', [node()]} - | {'other_groups', [group_tuple()]} - | {'monitoring', [pid()]}. +-type info_item() :: {'state', State :: sync_state()} + | {'own_group_name', GroupName :: group_name()} + | {'own_group_nodes', Nodes :: [node()]} + | {'synched_nodes', Nodes :: [node()]} + | {'sync_error', Nodes :: [node()]} + | {'no_contact', Nodes :: [node()]} + | {'other_groups', Groups :: [group_tuple()]} + | {'monitoring', Pids :: [pid()]}. -spec info() -> [info_item()]. info() -> @@ -1012,6 +1027,7 @@ grp_tuple({Name, normal, Nodes}) -> %%% The special process which checks that all nodes in the own global group %%% agrees on the configuration. %%%==================================================================================== +-spec sync_init(_, _, _, _) -> no_return(). sync_init(Type, Cname, PubType, Nodes) -> {Up, Down} = sync_check_node(lists:delete(node(), Nodes), [], []), sync_check_init(Type, Up, Cname, Nodes, Down, PubType). @@ -1032,9 +1048,11 @@ sync_check_node([Node|Nodes], Up, Down) -> %%% Check that all nodes are in agreement of the global %%% group configuration. %%%------------------------------------------------------------- +-spec sync_check_init(_, _, _, _, _, _) -> no_return(). sync_check_init(Type, Up, Cname, Nodes, Down, PubType) -> sync_check_init(Type, Up, Cname, Nodes, 3, [], Down, PubType). +-spec sync_check_init(_, _, _, _, _, _, _, _) -> no_return(). sync_check_init(_Type, NoContact, _Cname, _Nodes, 0, ErrorNodes, Down, _PubType) -> case ErrorNodes of [] -> diff --git a/lib/kernel/src/global_search.erl b/lib/kernel/src/global_search.erl index b723e18a1b..0bf53e29b8 100644 --- a/lib/kernel/src/global_search.erl +++ b/lib/kernel/src/global_search.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1998-2009. All Rights Reserved. +%% Copyright Ericsson AB 1998-2011. 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 @@ -69,6 +69,7 @@ start(Flag, Arg) -> %%%==================================================================================== %%%==================================================================================== +-spec init_send(_) -> no_return(). init_send({any, NodesList, Name, Msg, From}) -> case whereis_any_loop(NodesList, Name) of undefined -> @@ -115,6 +116,7 @@ init_send({node, Node, Name, Msg, From}) -> %%%==================================================================================== %%%==================================================================================== +-spec init_whereis(_) -> no_return(). init_whereis({any, NodesList, Name, From}) -> R = whereis_any_loop(NodesList, Name), gen_server:cast(global_group, {find_name_res, R, self(), From}), @@ -146,6 +148,7 @@ init_whereis({node, Node, Name, From}) -> %%%==================================================================================== %%%==================================================================================== %%%==================================================================================== +-spec init_names(_) -> no_return(). init_names({group, Nodes, From}) -> case names_group_loop(Nodes) of group_down -> diff --git a/lib/kernel/src/heart.erl b/lib/kernel/src/heart.erl index e78acfc7a6..255ae4e51b 100644 --- a/lib/kernel/src/heart.erl +++ b/lib/kernel/src/heart.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2010. All Rights Reserved. +%% Copyright Ericsson AB 1996-2011. 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 @@ -85,19 +85,21 @@ init(Starter, Parent) -> Starter ! {start_error, self()} end. --spec set_cmd(string()) -> 'ok' | {'error', {'bad_cmd', string()}}. +-spec set_cmd(Cmd) -> 'ok' | {'error', {'bad_cmd', Cmd}} when + Cmd :: string(). set_cmd(Cmd) -> heart ! {self(), set_cmd, Cmd}, wait(). --spec get_cmd() -> 'ok'. +-spec get_cmd() -> {ok, Cmd} when + Cmd :: string(). get_cmd() -> heart ! {self(), get_cmd}, wait(). --spec clear_cmd() -> {'ok', string()}. +-spec clear_cmd() -> ok. clear_cmd() -> heart ! {self(), clear_cmd}, diff --git a/lib/kernel/src/inet.erl b/lib/kernel/src/inet.erl index 327e0f93f1..5649188c38 100644 --- a/lib/kernel/src/inet.erl +++ b/lib/kernel/src/inet.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2010. All Rights Reserved. +%% Copyright Ericsson AB 1997-2011. 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 @@ -63,7 +63,8 @@ %% timer interface -export([start_timer/1, timeout/1, timeout/2, stop_timer/1]). --export_type([ip_address/0, socket/0]). +-export_type([family_option/0, hostent/0, hostname/0, ip4_address/0, + ip6_address/0, ip_address/0, posix/0, socket/0]). %% imports -import(lists, [append/1, duplicate/2, filter/2, foldl/3]). @@ -79,8 +80,16 @@ %%% --------------------------------- %%% Contract type definitions + +-type hostent() :: #hostent{}. +-type hostname() :: atom() | string(). +-type ip4_address() :: {0..255,0..255,0..255,0..255}. +-type ip6_address() :: {0..65535,0..65535,0..65535,0..65535, + 0..65535,0..65535,0..65535,0..65535}. +-type ip_address() :: ip4_address() | ip6_address(). +-type ip_port() :: 0..65535. +-type posix() :: exbadport | exbadseq | file:posix(). -type socket() :: port(). --type posix() :: atom(). -type socket_setopt() :: {'raw', non_neg_integer(), non_neg_integer(), binary()} | @@ -106,7 +115,7 @@ {'packet', 0 | 1 | 2 | 4 | 'raw' | 'sunrm' | 'asn1' | 'cdr' | 'fcgi' | 'line' | 'tpkt' | 'http' | 'httph' | 'http_bin' | 'httph_bin' } | - {'mode', list() | binary()} | + {'mode', 'list' | 'binary'} | {'port', 'port', 'term'} | {'exit_on_close', boolean()} | {'low_watermark', non_neg_integer()} | @@ -195,12 +204,13 @@ %%% --------------------------------- --spec get_rc() -> [{any(),any()}]. +-spec get_rc() -> [{Par :: any(), Val :: any()}]. get_rc() -> inet_db:get_rc(). --spec close(Socket :: socket()) -> 'ok'. +-spec close(Socket) -> 'ok' when + Socket :: socket(). close(Socket) -> prim_inet:close(Socket), @@ -211,8 +221,10 @@ close(Socket) -> ok end. --spec peername(Socket :: socket()) -> - {'ok', {ip_address(), non_neg_integer()}} | {'error', posix()}. +-spec peername(Socket) -> {ok, {Address, Port}} | {error, posix()} when + Socket :: socket(), + Address :: ip_address(), + Port :: non_neg_integer(). peername(Socket) -> prim_inet:peername(Socket). @@ -226,8 +238,10 @@ setpeername(Socket, undefined) -> prim_inet:setpeername(Socket, undefined). --spec sockname(Socket :: socket()) -> - {'ok', {ip_address(), non_neg_integer()}} | {'error', posix()}. +-spec sockname(Socket) -> {ok, {Address, Port}} | {error, posix()} when + Socket :: socket(), + Address :: ip_address(), + Port :: non_neg_integer(). sockname(Socket) -> prim_inet:sockname(Socket). @@ -260,8 +274,10 @@ send(Socket, Packet) -> setopts(Socket, Opts) -> prim_inet:setopts(Socket, Opts). --spec getopts(Socket :: socket(), Opts :: [socket_getopt()]) -> - {'ok', [socket_setopt()]} | {'error', posix()}. +-spec getopts(Socket, Options) -> + {'ok', [socket_setopt()]} | {'error', posix()} when + Socket :: socket(), + Options :: [socket_getopt()]. getopts(Socket, Opts) -> prim_inet:getopts(Socket, Opts). @@ -272,7 +288,19 @@ getopts(Socket, Opts) -> getifaddrs(Socket) -> prim_inet:getifaddrs(Socket). --spec getifaddrs() -> {'ok', [string()]} | {'error', posix()}. +-spec getifaddrs() -> {ok, Iflist} | {error, posix()} when + Iflist :: [{Ifname,[Ifopt]}], + Ifname :: string(), + Ifopt :: {flag,[Flag]} | {addr,Addr} | {netmask,Netmask} + | {broadaddr,Broadaddr} | {dstaddr,Dstaddr} + | {hwaddr,Hwaddr}, + Flag :: up | broadcast | loopback | pointtopoint + | running | multicast, + Addr :: ip_address(), + Netmask :: ip_address(), + Broadaddr :: ip_address(), + Dstaddr :: ip_address(), + Hwaddr :: [byte()]. getifaddrs() -> withsocket(fun(S) -> prim_inet:getifaddrs(S) end). @@ -371,7 +399,8 @@ popf(_Socket) -> % use of the DHCP-protocol % should never fail --spec gethostname() -> {'ok', string()}. +-spec gethostname() -> {'ok', Hostname} when + Hostname :: string(). gethostname() -> case inet_udp:open(0,[]) of @@ -402,19 +431,23 @@ getstat(Socket) -> getstat(Socket,What) -> prim_inet:getstat(Socket, What). --spec gethostbyname(Name :: string() | atom()) -> - {'ok', #hostent{}} | {'error', posix()}. +-spec gethostbyname(Hostname) -> {ok, Hostent} | {error, posix()} when + Hostname :: hostname(), + Hostent :: hostent(). gethostbyname(Name) -> gethostbyname_tm(Name, inet, false). --spec gethostbyname(Name :: string() | atom(), Family :: family_option()) -> - {'ok', #hostent{}} | {'error', posix()}. +-spec gethostbyname(Hostname, Family) -> + {ok, Hostent} | {error, posix()} when + Hostname :: hostname(), + Family :: family_option(), + Hostent :: hostent(). gethostbyname(Name,Family) -> gethostbyname_tm(Name, Family, false). --spec gethostbyname(Name :: string() | atom(), +-spec gethostbyname(Name :: hostname(), Family :: family_option(), Timeout :: non_neg_integer() | 'infinity') -> {'ok', #hostent{}} | {'error', posix()}. @@ -439,8 +472,9 @@ gethostbyname_tm(Name,Family,Timer) -> gethostbyname_tm(Name, Family, Timer, Opts). --spec gethostbyaddr(Address :: string() | ip_address()) -> - {'ok', #hostent{}} | {'error', posix()}. +-spec gethostbyaddr(Address) -> {ok, Hostent} | {error, posix()} when + Address :: string() | ip_address(), + Hostent :: hostent(). gethostbyaddr(Address) -> gethostbyaddr_tm(Address, false). @@ -491,14 +525,15 @@ getfd(Socket) -> %% Lookup an ip address %% --spec getaddr(Host :: ip_address() | string() | atom(), - Family :: family_option()) -> - {'ok', ip_address()} | {'error', posix()}. +-spec getaddr(Host, Family) -> {ok, Address} | {error, posix()} when + Host :: ip_address() | hostname(), + Family :: family_option(), + Address :: ip_address(). getaddr(Address, Family) -> getaddr(Address, Family, infinity). --spec getaddr(Host :: ip_address() | string() | atom(), +-spec getaddr(Host :: ip_address() | hostname(), Family :: family_option(), Timeout :: non_neg_integer() | 'infinity') -> {'ok', ip_address()} | {'error', posix()}. @@ -515,9 +550,11 @@ getaddr_tm(Address, Family, Timer) -> Error -> Error end. --spec getaddrs(Host :: ip_address() | string() | atom(), - Family :: family_option()) -> - {'ok', [ip_address()]} | {'error', posix()}. +-spec getaddrs(Host, Family) -> + {ok, Addresses} | {error, posix()} when + Host :: ip_address() | hostname(), + Family :: family_option(), + Addresses :: [ip_address()]. getaddrs(Address, Family) -> getaddrs(Address, Family, infinity). @@ -1237,7 +1274,8 @@ port_list(Name) -> %% utils %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec format_error(posix()) -> string(). +-spec format_error(Posix) -> string() when + Posix :: posix(). format_error(exbadport) -> "invalid port state"; format_error(exbadseq) -> "bad command sequence"; diff --git a/lib/kernel/src/inet_res.erl b/lib/kernel/src/inet_res.erl index 93563c6011..2276ddcd08 100644 --- a/lib/kernel/src/inet_res.erl +++ b/lib/kernel/src/inet_res.erl @@ -47,18 +47,93 @@ false -> ok end). +-type res_option() :: + {alt_nameservers, [nameserver()]} + | {edns, 0 | false} + | {inet6, boolean()} + | {nameservers, [nameserver()]} + | {recurse, boolean()} + | {retry, integer()} + | {timeout, integer()} + | {udp_payload_size, integer()} + | {usevc, boolean()}. + +-type nameserver() :: {inet:ip_address(), Port :: 1..65535}. + +-type res_error() :: formerr | qfmterror | servfail | nxdomain | + notimp | refused | badvers | timeout. + +-type dns_name() :: string(). + +-type rr_type() :: a | aaaa | cname | gid | hinfo | ns | mb | md | mg | mf + | minfo | mx | naptr | null | ptr | soa | spf | srv | txt + | uid | uinfo | unspec | wks. + +-type dns_class() :: in | chaos | hs | any. + +-opaque dns_msg() :: term(). + +-type dns_data() :: + dns_name() + | inet:ip4_address() + | inet:ip6_address() + | {MName :: dns_name(), + RName :: dns_name(), + Serial :: integer(), + Refresh :: integer(), + Retry :: integer(), + Expiry :: integer(), + Minimum :: integer()} + | {inet:ip4_address(), Proto :: integer(), BitMap :: binary()} + | {CpuString :: string(), OsString :: string()} + | {RM :: dns_name(), EM :: dns_name()} + | {Prio :: integer(), dns_name()} + | {Prio :: integer(),Weight :: integer(),Port :: integer(),dns_name()} + | {Order :: integer(),Preference :: integer(),Flags :: string(), + Services :: string(),Regexp :: string(), dns_name()} + | [string()] + | binary(). + %% -------------------------------------------------------------------------- %% resolve: %% %% Nameserver query %% +-spec resolve(Name, Class, Type) -> {ok, dns_msg()} | Error when + Name :: dns_name() | inet:ip_address(), + Class :: dns_class(), + Type :: rr_type(), + Error :: {error, Reason} | {error,{Reason,dns_msg()}}, + Reason :: inet:posix() | res_error(). + resolve(Name, Class, Type) -> resolve(Name, Class, Type, [], infinity). +-spec resolve(Name, Class, Type, Opts) -> + {ok, dns_msg()} | Error when + Name :: dns_name() | inet:ip_address(), + Class :: dns_class(), + Type :: rr_type(), + Opts :: [Opt], + Opt :: res_option() | verbose | atom(), + Error :: {error, Reason} | {error,{Reason,dns_msg()}}, + Reason :: inet:posix() | res_error(). + resolve(Name, Class, Type, Opts) -> resolve(Name, Class, Type, Opts, infinity). +-spec resolve(Name, Class, Type, Opts, Timeout) -> + {ok, dns_msg()} | Error when + Name :: dns_name() | inet:ip_address(), + Class :: dns_class(), + Type :: rr_type(), + Opts :: [Opt], + Opt :: res_option() | verbose | atom(), + Timeout :: timeout(), + Error :: {error, Reason} | {error,{Reason,dns_msg()}}, + Reason :: inet:posix() | res_error(). + resolve(Name, Class, Type, Opts, Timeout) -> case nsdname(Name) of {ok, Nm} -> @@ -76,12 +151,30 @@ resolve(Name, Class, Type, Opts, Timeout) -> %% Convenience wrapper to resolve/3,4,5 that filters out all answer data %% fields of the class and type asked for. +-spec lookup(Name, Class, Type) -> [dns_data()] when + Name :: dns_name() | inet:ip_address(), + Class :: dns_class(), + Type :: rr_type(). + lookup(Name, Class, Type) -> lookup(Name, Class, Type, []). +-spec lookup(Name, Class, Type, Opts) -> [dns_data()] when + Name :: dns_name() | inet:ip_address(), + Class :: dns_class(), + Type :: rr_type(), + Opts :: [res_option() | verbose]. + lookup(Name, Class, Type, Opts) -> lookup(Name, Class, Type, Opts, infinity). +-spec lookup(Name, Class, Type, Opts, Timeout) -> [dns_data()] when + Name :: dns_name() | inet:ip_address(), + Class :: dns_class(), + Type :: rr_type(), + Opts :: [res_option() | verbose], + Timeout :: timeout(). + lookup(Name, Class, Type, Opts, Timeout) -> lookup_filter(resolve(Name, Class, Type, Opts, Timeout), Class, Type). @@ -101,17 +194,55 @@ lookup_filter({error,_}, _, _) -> []. %% %% To be deprecated +-spec nslookup(Name, Class, Type) -> {ok, dns_msg()} | {error, Reason} when + Name :: dns_name() | inet:ip_address(), + Class :: dns_class(), + Type :: rr_type(), + Reason :: inet:posix() | res_error(). + nslookup(Name, Class, Type) -> do_nslookup(Name, Class, Type, [], infinity). +-spec nslookup(Name, Class, Type, Timeout) -> + {ok, dns_msg()} | {error, Reason} when + Name :: dns_name() | inet:ip_address(), + Class :: dns_class(), + Type :: rr_type(), + Timeout :: timeout(), + Reason :: inet:posix() | res_error(); + (Name, Class, Type, Nameservers) -> + {ok, dns_msg()} | {error, Reason} when + Name :: dns_name() | inet:ip_address(), + Class :: dns_class(), + Type :: rr_type(), + Nameservers :: [nameserver()], + Reason :: inet:posix() | res_error(). + nslookup(Name, Class, Type, Timeout) when is_integer(Timeout), Timeout >= 0 -> do_nslookup(Name, Class, Type, [], Timeout); nslookup(Name, Class, Type, NSs) -> % For backwards compatibility nnslookup(Name, Class, Type, NSs). % with OTP R6B only +-spec nnslookup(Name, Class, Type, Nameservers) -> + {ok, dns_msg()} | {error, Reason} when + Name :: dns_name() | inet:ip_address(), + Class :: dns_class(), + Type :: rr_type(), + Nameservers :: [nameserver()], + Reason :: inet:posix(). + nnslookup(Name, Class, Type, NSs) -> nnslookup(Name, Class, Type, NSs, infinity). +-spec nnslookup(Name, Class, Type, Nameservers, Timeout) -> + {ok, dns_msg()} | {error, Reason} when + Name :: dns_name() | inet:ip_address(), + Class :: dns_class(), + Type :: rr_type(), + Timeout :: timeout(), + Nameservers :: [nameserver()], + Reason :: inet:posix(). + nnslookup(Name, Class, Type, NSs, Timeout) -> do_nslookup(Name, Class, Type, [{nameservers,NSs}], Timeout). @@ -192,8 +323,19 @@ make_options(Opts, [Name|Names]) -> %% %% -------------------------------------------------------------------------- +-spec gethostbyaddr(Address) -> {ok, Hostent} | {error, Reason} when + Address :: inet:ip_address(), + Hostent :: inet:hostent(), + Reason :: inet:posix() | res_error(). + gethostbyaddr(IP) -> gethostbyaddr_tm(IP,false). +-spec gethostbyaddr(Address, Timeout) -> {ok, Hostent} | {error, Reason} when + Address :: inet:ip_address(), + Timeout :: timeout(), + Hostent :: inet:hostent(), + Reason :: inet:posix() | res_error(). + gethostbyaddr(IP,Timeout) -> Timer = inet:start_timer(Timeout), Res = gethostbyaddr_tm(IP,Timer), @@ -249,6 +391,11 @@ res_gethostbyaddr(Addr, IP, Timer) -> %% Caches the answer. %% -------------------------------------------------------------------------- +-spec gethostbyname(Name) -> {ok, Hostent} | {error, Reason} when + Name :: dns_name(), + Hostent :: inet:hostent(), + Reason :: inet:posix() | res_error(). + gethostbyname(Name) -> case inet_db:res_option(inet6) of true -> @@ -257,9 +404,23 @@ gethostbyname(Name) -> gethostbyname_tm(Name, inet, false) end. +-spec gethostbyname(Name, Family) -> {ok, Hostent} | {error, Reason} when + Name :: dns_name(), + Hostent :: inet:hostent(), + Family :: inet:family_option(), + Reason :: inet:posix() | res_error(). + gethostbyname(Name,Family) -> gethostbyname_tm(Name,Family,false). +-spec gethostbyname(Name, Family, Timeout) -> + {ok, Hostent} | {error, Reason} when + Name :: dns_name(), + Hostent :: inet:hostent(), + Timeout :: timeout(), + Family :: inet:family_option(), + Reason :: inet:posix() | res_error(). + gethostbyname(Name,Family,Timeout) -> Timer = inet:start_timer(Timeout), Res = gethostbyname_tm(Name,Family,Timer), @@ -298,14 +459,27 @@ gethostbyname_tm(_Name, _Family, _Timer) -> %% %% getbyname(domain_name(), Type) => {ok, hostent()} | {error, Reason} %% -%% where domain_name() is domain string or atom and Type is ?S_A, ?S_MX ... +%% where domain_name() is domain string and Type is ?S_A, ?S_MX ... %% %% Caches the answer. %% -------------------------------------------------------------------------- +-spec getbyname(Name, Type) -> {ok, Hostent} | {error, Reason} when + Name :: dns_name(), + Type :: rr_type(), + Hostent :: inet:hostent(), + Reason :: inet:posix() | res_error(). + getbyname(Name, Type) -> getbyname_tm(Name,Type,false). +-spec getbyname(Name, Type, Timeout) -> {ok, Hostent} | {error, Reason} when + Name :: dns_name(), + Type :: rr_type(), + Timeout :: timeout(), + Hostent :: inet:hostent(), + Reason :: inet:posix() | res_error(). + getbyname(Name, Type, Timeout) -> Timer = inet:start_timer(Timeout), Res = getbyname_tm(Name, Type, Timer), @@ -698,7 +872,7 @@ query_ns(S0, Id, Buffer, IP, Port, Timer, Retry, I, end end. -query_udp(_S, _Id, _Buffer, _IP, _Port, 0, Verbose) -> +query_udp(_S, _Id, _Buffer, _IP, _Port, 0, _Verbose) -> timeout; query_udp(S, Id, Buffer, IP, Port, Timeout, Verbose) -> ?verbose(Verbose, "Try UDP server : ~p:~p (timeout=~w)\n", @@ -734,7 +908,7 @@ query_udp(S, Id, Buffer, IP, Port, Timeout, Verbose) -> {error,econnrefused} end. -query_tcp(0, _Id, _Buffer, _IP, _Port, Verbose) -> +query_tcp(0, _Id, _Buffer, _IP, _Port, _Verbose) -> timeout; query_tcp(Timeout, Id, Buffer, IP, Port, Verbose) -> ?verbose(Verbose, "Try TCP server : ~p:~p (timeout=~w)\n", diff --git a/lib/kernel/src/inet_udp.erl b/lib/kernel/src/inet_udp.erl index 9a4089ab19..60bd96f332 100644 --- a/lib/kernel/src/inet_udp.erl +++ b/lib/kernel/src/inet_udp.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2009. All Rights Reserved. +%% Copyright Ericsson AB 1997-2011. 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 @@ -39,8 +39,10 @@ getserv(Name) when is_atom(Name) -> inet:getservbyname(Name,udp). getaddr(Address) -> inet:getaddr(Address, inet). getaddr(Address,Timer) -> inet:getaddr_tm(Address, inet, Timer). +-spec open(_) -> {ok, inet:socket()} | {error, atom()}. open(Port) -> open(Port, []). +-spec open(_, _) -> {ok, inet:socket()} | {error, atom()}. open(Port, Opts) -> case inet:udp_options( [{port,Port}, {recbuf, ?RECBUF} | Opts], @@ -69,6 +71,8 @@ recv(S,Len) -> recv(S,Len,Time) -> prim_inet:recvfrom(S, Len, Time). +-spec close(inet:socket()) -> ok. + close(S) -> inet:udp_close(S). diff --git a/lib/kernel/src/net_adm.erl b/lib/kernel/src/net_adm.erl index 737b1ecee9..9b2dac9544 100644 --- a/lib/kernel/src/net_adm.erl +++ b/lib/kernel/src/net_adm.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2009. All Rights Reserved. +%% Copyright Ericsson AB 1996-2011. 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 @@ -35,7 +35,11 @@ %% Try to read .hosts.erlang file in %% 1. cwd , 2. $HOME 3. init:root_dir() --spec host_file() -> [atom()] | {'error',atom() | {integer(),atom(),_}}. +-spec host_file() -> Hosts | {error, Reason} when + Hosts :: [Host :: atom()], + %% Copied from file:path_consult/2: + Reason :: file:posix() | badarg | terminated | system_limit + | {Line :: integer(), Mod :: module(), Term :: term()}. host_file() -> Home = case init:get_argument(home) of @@ -50,7 +54,8 @@ host_file() -> %% Check whether a node is up or down %% side effect: set up a connection to Node if there not yet is one. --spec ping(atom()) -> 'pang' | 'pong'. +-spec ping(Node) -> pong | pang when + Node :: atom(). ping(Node) when is_atom(Node) -> case catch gen:call({net_kernel, Node}, @@ -63,7 +68,8 @@ ping(Node) when is_atom(Node) -> pang end. --spec localhost() -> string(). +-spec localhost() -> Name when + Name :: string(). localhost() -> {ok, Host} = inet:gethostname(), @@ -73,12 +79,20 @@ localhost() -> end. --spec names() -> {'ok', [{string(), integer()}]} | {'error', _}. +-spec names() -> {ok, [{Name, Port}]} | {error, Reason} when + Name :: string(), + Port :: non_neg_integer(), + Reason :: address | file:posix(). names() -> names(localhost()). --spec names(atom() | string()) -> {'ok', [{string(), integer()}]} | {'error', _}. + +-spec names(Host) -> {ok, [{Name, Port}]} | {error, Reason} when + Host :: atom() | string(), + Name :: string(), + Port :: non_neg_integer(), + Reason :: address | file:posix(). names(Hostname) -> case inet:gethostbyname(Hostname) of @@ -88,8 +102,9 @@ names(Hostname) -> Else end. --spec dns_hostname(atom() | string()) -> - {'ok', string()} | {'error', atom() | string()}. +-spec dns_hostname(Host) -> {ok, Name} | {error, Host} when + Host :: atom() | string(), + Name :: string(). dns_hostname(Hostname) -> case inet:gethostbyname(Hostname) of @@ -164,7 +179,8 @@ collect_new(Sofar, Nodelist) -> world() -> world(silent). --spec world(verbosity()) -> [node()]. +-spec world(Arg) -> [node()] when + Arg :: verbosity(). world(Verbose) -> case net_adm:host_file() of @@ -172,12 +188,15 @@ world(Verbose) -> Hosts -> expand_hosts(Hosts, Verbose) end. --spec world_list([atom()]) -> [node()]. +-spec world_list(Hosts) -> [node()] when + Hosts :: [atom()]. world_list(Hosts) when is_list(Hosts) -> expand_hosts(Hosts, silent). --spec world_list([atom()], verbosity()) -> [node()]. +-spec world_list(Hosts, Arg) -> [node()] when + Hosts :: [atom()], + Arg :: verbosity(). world_list(Hosts, Verbose) when is_list(Hosts) -> expand_hosts(Hosts, Verbose). diff --git a/lib/kernel/src/net_kernel.erl b/lib/kernel/src/net_kernel.erl index 5228d4fe01..9e3d730cee 100644 --- a/lib/kernel/src/net_kernel.erl +++ b/lib/kernel/src/net_kernel.erl @@ -145,8 +145,15 @@ %% Interface functions kernel_apply(M,F,A) -> request({apply,M,F,A}). + +-spec allow(Nodes) -> ok | error when + Nodes :: [node()]. allow(Nodes) -> request({allow, Nodes}). + longnames() -> request(longnames). + +-spec stop() -> ok | {error, Reason} when + Reason :: not_allowed | not_found. stop() -> erl_distribution:stop(). node_info(Node) -> get_node_info(Node). @@ -158,10 +165,28 @@ i(Node) -> print_info(Node). verbose(Level) when is_integer(Level) -> request({verbose, Level}). +-spec set_net_ticktime(NetTicktime, TransitionPeriod) -> Res when + NetTicktime :: pos_integer(), + TransitionPeriod :: non_neg_integer(), + Res :: unchanged + | change_initiated + | {ongoing_change_to, NewNetTicktime}, + NewNetTicktime :: pos_integer(). set_net_ticktime(T, TP) when is_integer(T), T > 0, is_integer(TP), TP >= 0 -> ticktime_res(request({new_ticktime, T*250, TP*1000})). + +-spec set_net_ticktime(NetTicktime) -> Res when + NetTicktime :: pos_integer(), + Res :: unchanged + | change_initiated + | {ongoing_change_to, NewNetTicktime}, + NewNetTicktime :: pos_integer(). set_net_ticktime(T) when is_integer(T) -> set_net_ticktime(T, ?DEFAULT_TRANSITION_PERIOD). + +-spec get_net_ticktime() -> Res when + Res :: NetTicktime | {ongoing_change_to, NetTicktime} | ignored, + NetTicktime :: pos_integer(). get_net_ticktime() -> ticktime_res(request(ticktime)). @@ -171,6 +196,9 @@ get_net_ticktime() -> %% flags (we may want to move it elsewhere later). In order to easily %% be backward compatible, errors are created here when process_flag() %% fails. +-spec monitor_nodes(Flag) -> ok | Error when + Flag :: boolean(), + Error :: error | {error, term()}. monitor_nodes(Flag) -> case catch process_flag(monitor_nodes, Flag) of true -> ok; @@ -178,6 +206,13 @@ monitor_nodes(Flag) -> _ -> mk_monitor_nodes_error(Flag, []) end. +-spec monitor_nodes(Flag, Options) -> ok | Error when + Flag :: boolean(), + Options :: [Option], + Option :: {node_type, NodeType} + | nodedown_reason, + NodeType :: visible | hidden | all, + Error :: error | {error, term()}. monitor_nodes(Flag, Opts) -> case catch process_flag({monitor_nodes, Opts}, Flag) of true -> ok; @@ -209,6 +244,8 @@ publish_on_node(Node) when is_atom(Node) -> update_publish_nodes(Ns) -> request({update_publish_nodes, Ns}). +-spec connect_node(Node) -> boolean() | ignored when + Node :: node(). %% explicit connects connect_node(Node) when is_atom(Node) -> request({connect, normal, Node}). diff --git a/lib/kernel/src/os.erl b/lib/kernel/src/os.erl index d1feae771d..f6769df585 100644 --- a/lib/kernel/src/os.erl +++ b/lib/kernel/src/os.erl @@ -24,7 +24,10 @@ -include("file.hrl"). --spec type() -> 'vxworks' | {'unix',atom()} | {'win32',atom()} | {'ose',atom()}. +-spec type() -> vxworks | {Osfamily, Osname} when + Osfamily :: unix | win32, + Osname :: atom(). + type() -> case erlang:system_info(os_type) of {vxworks, _} -> @@ -32,18 +35,27 @@ type() -> Else -> Else end. --spec version() -> string() | {non_neg_integer(),non_neg_integer(),non_neg_integer()}. +-spec version() -> VersionString | {Major, Minor, Release} when + VersionString :: string(), + Major :: non_neg_integer(), + Minor :: non_neg_integer(), + Release :: non_neg_integer(). version() -> erlang:system_info(os_version). --spec find_executable(string()) -> string() | 'false'. +-spec find_executable(Name) -> Filename | 'false' when + Name :: string(), + Filename :: string(). find_executable(Name) -> case os:getenv("PATH") of false -> find_executable(Name, []); Path -> find_executable(Name, Path) end. --spec find_executable(string(), string()) -> string() | 'false'. +-spec find_executable(Name, Path) -> Filename | 'false' when + Name :: string(), + Path :: string(), + Filename :: string(). find_executable(Name, Path) -> Extensions = extensions(), case filename:pathtype(Name) of @@ -147,7 +159,8 @@ extensions() -> end. %% Executes the given command in the default shell for the operating system. --spec cmd(atom() | string() | [string()]) -> string(). +-spec cmd(Command) -> string() when + Command :: atom() | io_lib:chars(). cmd(Cmd) -> validate(Cmd), case type() of diff --git a/lib/kernel/src/pg2.erl b/lib/kernel/src/pg2.erl index 956a900adc..0d5838716e 100644 --- a/lib/kernel/src/pg2.erl +++ b/lib/kernel/src/pg2.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2010. All Rights Reserved. +%% Copyright Ericsson AB 1997-2011. 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,17 +30,19 @@ %%% Exported functions %%% --spec start_link() -> {'ok', pid()} | {'error', term()}. +-spec start_link() -> {'ok', pid()} | {'error', any()}. start_link() -> gen_server:start_link({local, ?MODULE}, ?MODULE, [], []). --spec start() -> {'ok', pid()} | {'error', term()}. +-spec start() -> {'ok', pid()} | {'error', any()}. start() -> ensure_started(). --spec create(term()) -> 'ok'. +-type name() :: any(). + +-spec create(Name :: name()) -> 'ok'. create(Name) -> ensure_started(), @@ -55,9 +57,7 @@ create(Name) -> ok end. --type name() :: term(). - --spec delete(name()) -> 'ok'. +-spec delete(Name :: name()) -> 'ok'. delete(Name) -> ensure_started(), @@ -67,7 +67,8 @@ delete(Name) -> end), ok. --spec join(name(), pid()) -> 'ok' | {'error', {'no_such_group', term()}}. +-spec join(Name, Pid :: pid()) -> 'ok' | {'error', {'no_such_group', Name}} + when Name :: name(). join(Name, Pid) when is_pid(Pid) -> ensure_started(), @@ -83,7 +84,8 @@ join(Name, Pid) when is_pid(Pid) -> ok end. --spec leave(name(), pid()) -> 'ok' | {'error', {'no_such_group', name()}}. +-spec leave(Name, Pid :: pid()) -> 'ok' | {'error', {'no_such_group', Name}} + when Name :: name(). leave(Name, Pid) when is_pid(Pid) -> ensure_started(), @@ -99,10 +101,9 @@ leave(Name, Pid) when is_pid(Pid) -> ok end. --type get_members_ret() :: [pid()] | {'error', {'no_such_group', name()}}. +-spec get_members(Name) -> [pid()] | {'error', {'no_such_group', Name}} + when Name :: name(). --spec get_members(name()) -> get_members_ret(). - get_members(Name) -> ensure_started(), case ets:member(pg2_table, {group, Name}) of @@ -112,7 +113,8 @@ get_members(Name) -> {error, {no_such_group, Name}} end. --spec get_local_members(name()) -> get_members_ret(). +-spec get_local_members(Name) -> [pid()] | {'error', {'no_such_group', Name}} + when Name :: name(). get_local_members(Name) -> ensure_started(), @@ -123,15 +125,15 @@ get_local_members(Name) -> {error, {no_such_group, Name}} end. --spec which_groups() -> [name()]. +-spec which_groups() -> [Name :: name()]. which_groups() -> ensure_started(), all_groups(). --type gcp_error_reason() :: {'no_process', term()} | {'no_such_group', term()}. - --spec get_closest_pid(term()) -> pid() | {'error', gcp_error_reason()}. +-spec get_closest_pid(Name) -> pid() | {'error', Reason} when + Name :: name(), + Reason :: {'no_process', Name} | {'no_such_group', Name}. get_closest_pid(Name) -> case get_local_members(Name) of @@ -157,7 +159,9 @@ get_closest_pid(Name) -> -record(state, {}). --spec init([]) -> {'ok', #state{}}. +-opaque state() :: #state{}. + +-spec init(Arg :: []) -> {'ok', state()}. init([]) -> Ns = nodes(), @@ -169,13 +173,13 @@ init([]) -> pg2_table = ets:new(pg2_table, [ordered_set, protected, named_table]), {ok, #state{}}. --type call() :: {'create', name()} - | {'delete', name()} - | {'join', name(), pid()} - | {'leave', name(), pid()}. - --spec handle_call(call(), _, #state{}) -> - {'reply', 'ok', #state{}}. +-spec handle_call(Call :: {'create', Name} + | {'delete', Name} + | {'join', Name, Pid :: pid()} + | {'leave', Name, Pid :: pid()}, + From :: {pid(),Tag :: any()}, + State :: state()) -> {'reply', 'ok', state()} + when Name :: name(). handle_call({create, Name}, _From, S) -> assure_group(Name), @@ -195,11 +199,10 @@ handle_call(Request, From, S) -> [Request, From]), {noreply, S}. --type all_members() :: [[name(),...]]. --type cast() :: {'exchange', node(), all_members()} - | {'del_member', name(), pid()}. - --spec handle_cast(cast(), #state{}) -> {'noreply', #state{}}. +-spec handle_cast(Cast :: {'exchange', node(), Names :: [[Name,...]]} + | {'del_member', Name, Pid :: pid()}, + State :: state()) -> {'noreply', state()} + when Name :: name(). handle_cast({exchange, _Node, List}, S) -> store(List), @@ -208,7 +211,8 @@ handle_cast(_, S) -> %% Ignore {del_member, Name, Pid}. {noreply, S}. --spec handle_info(tuple(), #state{}) -> {'noreply', #state{}}. +-spec handle_info(Tuple :: tuple(), State :: state()) -> + {'noreply', state()}. handle_info({'DOWN', MonitorRef, process, _Pid, _Info}, S) -> member_died(MonitorRef), @@ -222,7 +226,7 @@ handle_info({new_pg2, Node}, S) -> handle_info(_, S) -> {noreply, S}. --spec terminate(term(), #state{}) -> 'ok'. +-spec terminate(Reason :: any(), State :: state()) -> 'ok'. terminate(_Reason, _S) -> true = ets:delete(pg2_table), diff --git a/lib/kernel/src/rpc.erl b/lib/kernel/src/rpc.erl index e09acb5024..be35f99ed2 100644 --- a/lib/kernel/src/rpc.erl +++ b/lib/kernel/src/rpc.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2010. All Rights Reserved. +%% Copyright Ericsson AB 1996-2011. 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 @@ -263,14 +263,28 @@ proxy_user_flush() -> %% THE rpc client interface --spec call(node(), atom(), atom(), [term()]) -> term(). +-spec call(Node, Module, Function, Args) -> Res | {badrpc, Reason} when + Node :: node(), + Module :: module(), + Function :: atom(), + Args :: [term()], + Res :: term(), + Reason :: term(). call(N,M,F,A) when node() =:= N -> %% Optimize local call local_call(M, F, A); call(N,M,F,A) -> do_call(N, {call,M,F,A,group_leader()}, infinity). --spec call(node(), atom(), atom(), [term()], timeout()) -> term(). +-spec call(Node, Module, Function, Args, Timeout) -> + Res | {badrpc, Reason} when + Node :: node(), + Module :: module(), + Function :: atom(), + Args :: [term()], + Res :: term(), + Reason :: term(), + Timeout :: timeout(). call(N,M,F,A,_Timeout) when node() =:= N -> %% Optimize local call local_call(M,F,A); @@ -279,14 +293,28 @@ call(N,M,F,A,infinity) -> call(N,M,F,A,Timeout) when is_integer(Timeout), Timeout >= 0 -> do_call(N, {call,M,F,A,group_leader()}, Timeout). --spec block_call(node(), atom(), atom(), [term()]) -> term(). +-spec block_call(Node, Module, Function, Args) -> Res | {badrpc, Reason} when + Node :: node(), + Module :: module(), + Function :: atom(), + Args :: [term()], + Res :: term(), + Reason :: term(). block_call(N,M,F,A) when node() =:= N -> %% Optimize local call local_call(M,F,A); block_call(N,M,F,A) -> do_call(N, {block_call,M,F,A,group_leader()}, infinity). --spec block_call(node(), atom(), atom(), [term()], timeout()) -> term(). +-spec block_call(Node, Module, Function, Args, Timeout) -> + Res | {badrpc, Reason} when + Node :: node(), + Module :: module(), + Function :: atom(), + Args :: [term()], + Res :: term(), + Reason :: term(), + Timeout :: timeout(). block_call(N,M,F,A,_Timeout) when node() =:= N -> %% Optimize local call local_call(M, F, A); @@ -339,7 +367,13 @@ rpc_check(X) -> X. %% The entire call is packed into an atomic transaction which %% either succeeds or fails, i.e. never hangs (unless the server itself hangs). --spec server_call(node(), atom(), term(), term()) -> term() | {'error', 'nodedown'}. +-spec server_call(Node, Name, ReplyWrapper, Msg) -> Reply | {error, Reason} when + Node :: node(), + Name :: atom(), + ReplyWrapper :: term(), + Msg :: term(), + Reply :: term(), + Reason :: nodedown. server_call(Node, Name, ReplyWrapper, Msg) when is_atom(Node), is_atom(Name) -> @@ -362,7 +396,11 @@ server_call(Node, Name, ReplyWrapper, Msg) end end. --spec cast(node(), atom(), atom(), [term()]) -> 'true'. +-spec cast(Node, Module, Function, Args) -> true when + Node :: node(), + Module :: module(), + Function :: atom(), + Args :: [term()]. cast(Node, Mod, Fun, Args) when Node =:= node() -> catch spawn(Mod, Fun, Args), @@ -373,12 +411,17 @@ cast(Node, Mod, Fun, Args) -> %% Asynchronous broadcast, returns nothing, it's just send'n prey --spec abcast(atom(), term()) -> 'abcast'. +-spec abcast(Name, Msg) -> abcast when + Name :: atom(), + Msg :: term(). abcast(Name, Mess) -> abcast([node() | nodes()], Name, Mess). --spec abcast([node()], atom(), term()) -> 'abcast'. +-spec abcast(Nodes, Name, Msg) -> abcast when + Nodes :: [node()], + Name :: atom(), + Msg :: term(). abcast([Node|Tail], Name, Mess) -> Dest = {Name,Node}, @@ -396,23 +439,39 @@ abcast([], _,_) -> abcast. %% message when we return from the call, we can't know that they have %% processed the message though. --spec sbcast(atom(), term()) -> {[node()], [node()]}. +-spec sbcast(Name, Msg) -> {GoodNodes, BadNodes} when + Name :: atom(), + Msg :: term(), + GoodNodes :: [node()], + BadNodes :: [node()]. sbcast(Name, Mess) -> sbcast([node() | nodes()], Name, Mess). --spec sbcast([node()], atom(), term()) -> {[node()], [node()]}. +-spec sbcast(Nodes, Name, Msg) -> {GoodNodes, BadNodes} when + Name :: atom(), + Msg :: term(), + Nodes :: [node()], + GoodNodes :: [node()], + BadNodes :: [node()]. sbcast(Nodes, Name, Mess) -> Monitors = send_nodes(Nodes, ?NAME, {sbcast, Name, Mess}, []), rec_nodes(?NAME, Monitors). --spec eval_everywhere(atom(), atom(), [term()]) -> 'abcast'. +-spec eval_everywhere(Module, Function, Args) -> abcast when + Module :: module(), + Function :: atom(), + Args :: [term()]. eval_everywhere(Mod, Fun, Args) -> eval_everywhere([node() | nodes()] , Mod, Fun, Args). --spec eval_everywhere([node()], atom(), atom(), [term()]) -> 'abcast'. +-spec eval_everywhere(Nodes, Module, Function, Args) -> abcast when + Nodes :: [node()], + Module :: module(), + Function :: atom(), + Args :: [term()]. eval_everywhere(Nodes, Mod, Fun, Args) -> gen_server:abcast(Nodes, ?NAME, {cast,Mod,Fun,Args,group_leader()}). @@ -453,20 +512,45 @@ unmonitor(Ref) when is_reference(Ref) -> %% Call apply(M,F,A) on all nodes in parallel --spec multicall(atom(), atom(), [term()]) -> {[_], [node()]}. +-spec multicall(Module, Function, Args) -> {ResL, BadNodes} when + Module :: module(), + Function :: atom(), + Args :: [term()], + ResL :: [term()], + BadNodes :: [node()]. multicall(M, F, A) -> multicall(M, F, A, infinity). --spec multicall([node()], atom(), atom(), [term()]) -> {[_], [node()]} - ; (atom(), atom(), [term()], timeout()) -> {[_], [node()]}. +-spec multicall(Nodes, Module, Function, Args) -> {ResL, BadNodes} when + Nodes :: [node()], + Module :: module(), + Function :: atom(), + Args :: [term()], + ResL :: [term()], + BadNodes :: [node()]; + (Module, Function, Args, Timeout) -> {ResL, BadNodes} when + Module :: module(), + Function :: atom(), + Args :: [term()], + Timeout :: timeout(), + ResL :: [term()], + BadNodes :: [node()]. multicall(Nodes, M, F, A) when is_list(Nodes) -> multicall(Nodes, M, F, A, infinity); multicall(M, F, A, Timeout) -> multicall([node() | nodes()], M, F, A, Timeout). --spec multicall([node()], atom(), atom(), [term()], timeout()) -> {[_], [node()]}. +-spec multicall(Nodes, Module, Function, Args, Timeout) -> + {ResL, BadNodes} when + Nodes :: [node()], + Module :: module(), + Function :: atom(), + Args :: [term()], + Timeout :: timeout(), + ResL :: [term()], + BadNodes :: [node()]. multicall(Nodes, M, F, A, infinity) when is_list(Nodes), is_atom(M), is_atom(F), is_list(A) -> @@ -495,12 +579,21 @@ do_multicall(Nodes, M, F, A, Timeout) -> %% %% There is no apparent order among the replies. --spec multi_server_call(atom(), term()) -> {[_], [node()]}. +-spec multi_server_call(Name, Msg) -> {Replies, BadNodes} when + Name :: atom(), + Msg :: term(), + Replies :: [Reply :: term()], + BadNodes :: [node()]. multi_server_call(Name, Msg) -> multi_server_call([node() | nodes()], Name, Msg). --spec multi_server_call([node()], atom(), term()) -> {[_], [node()]}. +-spec multi_server_call(Nodes, Name, Msg) -> {Replies, BadNodes} when + Nodes :: [node()], + Name :: atom(), + Msg :: term(), + Replies :: [Reply :: term()], + BadNodes :: [node()]. multi_server_call(Nodes, Name, Msg) when is_list(Nodes), is_atom(Name) -> @@ -509,9 +602,22 @@ multi_server_call(Nodes, Name, Msg) %% Deprecated functions. Were only needed when communicating with R6 nodes. +-spec safe_multi_server_call(Name, Msg) -> {Replies, BadNodes} when + Name :: atom(), + Msg :: term(), + Replies :: [Reply :: term()], + BadNodes :: [node()]. + safe_multi_server_call(Name, Msg) -> multi_server_call(Name, Msg). +-spec safe_multi_server_call(Nodes, Name, Msg) -> {Replies, BadNodes} when + Nodes :: [node()], + Name :: atom(), + Msg :: term(), + Replies :: [Reply :: term()], + BadNodes :: [node()]. + safe_multi_server_call(Nodes, Name, Msg) -> multi_server_call(Nodes, Name, Msg). @@ -539,7 +645,14 @@ rec_nodes(Name, [{N,R} | Tail], Badnodes, Replies) -> %% rpc's towards the same node. I.e. it returns immediately and %% it returns a Key that can be used in a subsequent yield(Key). --spec async_call(node(), atom(), atom(), [term()]) -> pid(). +-opaque key() :: pid(). + +-spec async_call(Node, Module, Function, Args) -> Key when + Node :: node(), + Module :: module(), + Function :: atom(), + Args :: [term()], + Key :: key(). async_call(Node, Mod, Fun, Args) -> ReplyTo = self(), @@ -549,20 +662,27 @@ async_call(Node, Mod, Fun, Args) -> ReplyTo ! {self(), {promise_reply, R}} %% self() is key end). --spec yield(pid()) -> term(). +-spec yield(Key) -> {value, Val} | timeout when + Key :: key(), + Val :: (Res :: term()) | {badrpc, Reason :: term()}. yield(Key) when is_pid(Key) -> {value,R} = do_yield(Key, infinity), R. --spec nb_yield(pid(), timeout()) -> {'value', _} | 'timeout'. +-spec nb_yield(Key, Timeout) -> {value, Val} | timeout when + Key :: key(), + Timeout :: timeout(), + Val :: (Res :: term()) | {badrpc, Reason :: term()}. nb_yield(Key, infinity=Inf) when is_pid(Key) -> do_yield(Key, Inf); nb_yield(Key, Timeout) when is_pid(Key), is_integer(Timeout), Timeout >= 0 -> do_yield(Key, Timeout). --spec nb_yield(pid()) -> {'value', _} | 'timeout'. +-spec nb_yield(Key) -> {value, Val} | timeout when + Key :: key(), + Val :: (Res :: term()) | {badrpc, Reason :: term()}. nb_yield(Key) when is_pid(Key) -> do_yield(Key, 0). @@ -582,7 +702,12 @@ do_yield(Key, Timeout) -> %% ArgL === [{M,F,Args},........] %% Returns a lists of the evaluations in the same order as %% given to ArgL --spec parallel_eval([{atom(), atom(), [_]}]) -> [_]. +-spec parallel_eval(FuncCalls) -> ResL when + FuncCalls :: [{Module, Function, Args}], + Module :: module(), + Function :: atom(), + Args :: [term()], + ResL :: [term()]. parallel_eval(ArgL) -> Nodes = [node() | nodes()], @@ -599,7 +724,13 @@ map_nodes([{M,F,A}|Tail],[Node|MoreNodes], Original) -> %% Parallel version of lists:map/3 with exactly the same %% arguments and return value as lists:map/3, %% except that it calls exit/1 if a network error occurs. --spec pmap({atom(),atom()}, [term()], [term()]) -> [term()]. +-spec pmap(FuncSpec, ExtraArgs, List1) -> List2 when + FuncSpec :: {Module,Function}, + Module :: module(), + Function :: atom(), + ExtraArgs :: [term()], + List1 :: [Elem :: term()], + List2 :: [term()]. pmap({M,F}, As, List) -> check(parallel_eval(build_args(M,F,As, List, [])), []). @@ -616,15 +747,20 @@ check([], Ack) -> Ack. %% location transparent version of process_info --spec pinfo(pid()) -> [{atom(), _}] | 'undefined'. +-spec pinfo(Pid) -> [{Item, Info}] | undefined when + Pid :: pid(), + Item :: atom(), + Info :: term(). pinfo(Pid) when node(Pid) =:= node() -> process_info(Pid); pinfo(Pid) -> call(node(Pid), erlang, process_info, [Pid]). --spec pinfo(pid(), Item) -> {Item, _} | 'undefined' | [] - when is_subtype(Item, atom()). +-spec pinfo(Pid, Item) -> {Item, Info} | undefined | [] when + Pid :: pid(), + Item :: atom(), + Info :: term(). pinfo(Pid, Item) when node(Pid) =:= node() -> process_info(Pid, Item); diff --git a/lib/kernel/src/seq_trace.erl b/lib/kernel/src/seq_trace.erl index 78c3040f21..ea5da2de1c 100644 --- a/lib/kernel/src/seq_trace.erl +++ b/lib/kernel/src/seq_trace.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1998-2009. All Rights Reserved. +%% Copyright Ericsson AB 1998-2011. 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 @@ -38,15 +38,17 @@ -type flag() :: 'send' | 'receive' | 'print' | 'timestamp'. -type component() :: 'label' | 'serial' | flag(). --type value() :: non_neg_integer() - | {non_neg_integer(), non_neg_integer()} - | boolean(). --type token_pair() :: {component(), value()}. +-type value() :: (Integer :: non_neg_integer()) + | {Previous :: non_neg_integer(), + Current :: non_neg_integer()} + | (Bool :: boolean()). %%--------------------------------------------------------------------------- --type token() :: [] | {integer(), boolean(), _, _, _}. --spec set_token(token()) -> token() | 'ok'. +-opaque token() :: {integer(), boolean(), _, _, _}. +-spec set_token(Token) -> PreviousToken | 'ok' when + Token :: [] | token(), + PreviousToken :: [] | token(). set_token([]) -> erlang:seq_trace(sequential_trace_token,[]); @@ -58,28 +60,35 @@ set_token({Flags,Label,Serial,_From,Lastcnt}) -> %% expects that, the BIF can however "unofficially" handle atoms as well, and %% atoms can be used if only Erlang nodes are involved --spec set_token(component(), value()) -> token_pair(). +-spec set_token(Component, Val) -> {Component, OldVal} when + Component :: component(), + Val :: value(), + OldVal :: value(). set_token(Type, Val) -> erlang:seq_trace(Type, Val). --spec get_token() -> term(). +-spec get_token() -> [] | token(). get_token() -> element(2,process_info(self(),sequential_trace_token)). --spec get_token(component()) -> token_pair(). - +-spec get_token(Component) -> {Component, Val} when + Component :: component(), + Val :: value(). get_token(Type) -> erlang:seq_trace_info(Type). --spec print(term()) -> 'ok'. +-spec print(TraceInfo) -> 'ok' when + TraceInfo :: term(). print(Term) -> erlang:seq_trace_print(Term), ok. --spec print(integer(), term()) -> 'ok'. +-spec print(Label, TraceInfo) -> 'ok' when + Label :: integer(), + TraceInfo :: term(). print(Label, Term) when is_atom(Label) -> erlang:error(badarg, [Label, Term]); @@ -94,14 +103,17 @@ reset_trace() -> %% reset_trace(Pid) -> % this might be a useful function too --type tracer() :: pid() | port() | 'false'. +-type tracer() :: (Pid :: pid()) | port() | 'false'. --spec set_system_tracer(tracer()) -> tracer(). +-spec set_system_tracer(Tracer) -> OldTracer when + Tracer :: tracer(), + OldTracer :: tracer(). set_system_tracer(Pid) -> erlang:system_flag(sequential_tracer, Pid). --spec get_system_tracer() -> tracer(). +-spec get_system_tracer() -> Tracer when + Tracer :: tracer(). get_system_tracer() -> element(2, erlang:system_info(sequential_tracer)). diff --git a/lib/kernel/src/wrap_log_reader.erl b/lib/kernel/src/wrap_log_reader.erl index fabaa07752..c41e0091e4 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-2010. All Rights Reserved. +%% Copyright Ericsson AB 1998-2011. 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 @@ -41,6 +41,8 @@ first_no :: non_neg_integer() | 'one' % first read file number }). +-opaque continuation() :: #wrap_reader{}. + %% %% Exported functions %% @@ -50,9 +52,11 @@ %% is not yet reached, we are on the first 'round' of filling the wrap %% files. --type open_ret() :: {'ok', #wrap_reader{}} | {'error', tuple()}. +-type open_ret() :: {'ok', Continuation :: continuation()} + | {'error', Reason :: tuple()}. --spec open(atom() | string()) -> open_ret(). +-spec open(Filename) -> open_ret() when + Filename :: string() | atom(). open(File) when is_atom(File) -> open(atom_to_list(File)); @@ -77,7 +81,9 @@ open(File) when is_list(File) -> Error end. --spec open(atom() | string(), integer()) -> open_ret(). +-spec open(Filename, N) -> open_ret() when + Filename :: string() | atom(), + N :: integer(). open(File, FileNo) when is_atom(File), is_integer(FileNo) -> open(atom_to_list(File), FileNo); @@ -100,22 +106,29 @@ open(File, FileNo) when is_list(File), is_integer(FileNo) -> Error end. --spec close(#wrap_reader{}) -> 'ok' | {'error', atom()}. +-spec close(Continuation) -> 'ok' | {'error', Reason} when + Continuation :: continuation(), + Reason :: file:posix(). close(#wrap_reader{fd = FD}) -> file:close(FD). --type chunk_ret() :: {#wrap_reader{}, [term()]} - | {#wrap_reader{}, [term()], non_neg_integer()} - | {#wrap_reader{}, 'eof'} - | {'error', term()}. +-type chunk_ret() :: {Continuation2, Terms :: [term()]} + | {Continuation2, + Terms :: [term()], + Badbytes :: non_neg_integer()} + | {Continuation2, 'eof'} + | {'error', Reason :: term()}. --spec chunk(#wrap_reader{}) -> chunk_ret(). +-spec chunk(Continuation) -> chunk_ret() when + Continuation :: continuation(). chunk(WR = #wrap_reader{}) -> chunk(WR, ?MAX_CHUNK_SIZE, 0). --spec chunk(#wrap_reader{}, 'infinity' | pos_integer()) -> chunk_ret(). +-spec chunk(Continuation, N) -> chunk_ret() when + Continuation :: continuation(), + N :: infinity | pos_integer(). chunk(WR = #wrap_reader{}, infinity) -> chunk(WR, ?MAX_CHUNK_SIZE, 0); |