aboutsummaryrefslogtreecommitdiffstats
path: root/erts/preloaded/src/erlang.erl
diff options
context:
space:
mode:
Diffstat (limited to 'erts/preloaded/src/erlang.erl')
-rw-r--r--erts/preloaded/src/erlang.erl336
1 files changed, 233 insertions, 103 deletions
diff --git a/erts/preloaded/src/erlang.erl b/erts/preloaded/src/erlang.erl
index 646acf5798..061db72dd8 100644
--- a/erts/preloaded/src/erlang.erl
+++ b/erts/preloaded/src/erlang.erl
@@ -79,6 +79,7 @@
-export([bump_reductions/1, byte_size/1, call_on_load_function/1]).
-export([cancel_timer/1, check_old_code/1, check_process_code/2, crc32/1]).
-export([crc32/2, crc32_combine/3, date/0, decode_packet/3]).
+-export([delete_element/2]).
-export([delete_module/1, demonitor/1, demonitor/2, display/1]).
-export([display_nl/0, display_string/1, dist_exit/3, erase/0, erase/1]).
-export([error/1, error/2, exit/1, exit/2, external_size/1]).
@@ -88,6 +89,7 @@
-export([garbage_collect_message_area/0, get/0, get/1, get_keys/1]).
-export([get_module_info/1, get_stacktrace/0, group_leader/0]).
-export([group_leader/2, halt/0, halt/1, halt/2, hash/2, hibernate/3]).
+-export([insert_element/3]).
-export([integer_to_list/1, iolist_size/1, iolist_to_binary/1]).
-export([is_alive/0, is_builtin/3, is_process_alive/1, length/1, link/1]).
-export([list_to_atom/1, list_to_binary/1, list_to_bitstr/1]).
@@ -529,6 +531,14 @@ date() ->
decode_packet(_Type, _Bin, _Options) ->
erlang:nif_error(undefined).
+%% delete_element/2
+-spec erlang:delete_element(Index, Tuple1) -> Tuple2 when
+ Index :: pos_integer(),
+ Tuple1 :: tuple(),
+ Tuple2 :: tuple().
+delete_element(_Index, _Tuple1) ->
+ erlang:nif_error(undefined).
+
%% delete_module/1
-spec delete_module(Module) -> true | undefined when
Module :: module().
@@ -820,6 +830,15 @@ hash(_Term, _Range) ->
hibernate(_Module, _Function, _Args) ->
erlang:nif_error(undefined).
+%% insert_element/3
+-spec erlang:insert_element(Index, Tuple1, Term) -> Tuple2 when
+ Index :: pos_integer(),
+ Tuple1 :: tuple(),
+ Tuple2 :: tuple(),
+ Term :: term().
+insert_element(_Index, _Tuple1, _Term) ->
+ erlang:nif_error(undefined).
+
%% integer_to_list/1
-spec integer_to_list(Integer) -> string() when
Integer :: integer().
@@ -1075,57 +1094,6 @@ phash2(_Term, _Range) ->
pid_to_list(_Pid) ->
erlang:nif_error(undefined).
-%% port_close/1
--spec port_close(Port) -> true when
- Port :: port() | atom().
-port_close(_Port) ->
- erlang:nif_error(undefined).
-
-%% port_command/2
--spec port_command(Port, Data) -> true when
- Port :: port() | atom(),
- Data :: iodata().
-port_command(_Port, _Data) ->
- erlang:nif_error(undefined).
-
-%% port_command/3
--spec port_command(Port, Data, OptionList) -> boolean() when
- Port :: port() | atom(),
- Data :: iodata(),
- OptionList :: [Option],
- Option :: force | nosuspend.
-port_command(_Port, _Data, _OptionList) ->
- erlang:nif_error(undefined).
-
-%% port_connect/2
--spec port_connect(Port, Pid) -> true when
- Port :: port() | atom(),
- Pid :: pid().
-port_connect(_Port, _Pid) ->
- erlang:nif_error(undefined).
-
-%% port_control/3
--spec port_control(Port, Operation, Data) -> Res when
- Port :: port() | atom(),
- Operation :: integer(),
- Data :: iodata(),
- Res :: string() | binary().
-port_control(_Port, _Operation, _Data) ->
- erlang:nif_error(undefined).
-
-%% port_get_data/1
--spec erlang:port_get_data(P1) -> term() when
- P1 :: port() | atom().
-port_get_data(_P1) ->
- erlang:nif_error(undefined).
-
-%% port_set_data/2
--spec erlang:port_set_data(P1, P2) -> true when
- P1 :: port() | atom(),
- P2 :: term().
-port_set_data(_P1, _P2) ->
- erlang:nif_error(undefined).
-
%% port_to_list/1
-spec erlang:port_to_list(Port) -> string() when
Port :: port().
@@ -1699,60 +1667,12 @@ nodes(_Arg) ->
| in
| out
| binary
- | eof.
+ | eof
+ | {parallelism, Boolean :: boolean()}
+ | hide.
open_port(_PortName,_PortSettings) ->
erlang:nif_error(undefined).
-%% Shadowed by erl_bif_types: erlang:port_call/2
--spec erlang:port_call(Port, Data) -> term() when
- Port :: port() | atom(),
- Data :: term().
-port_call(_Port, _Data) ->
- erlang:nif_error(undefined).
-
-%% Shadowed by erl_bif_types: erlang:port_call/3
--spec erlang:port_call(Port, Operation, Data) -> term() when
- Port :: port() | atom(),
- Operation :: integer(),
- Data :: term().
-port_call(_Port, _Operation, _Data) ->
- erlang:nif_error(undefined).
-
--type port_info_item() ::
- registered_name |
- id |
- connected |
- links |
- name |
- input |
- output |
- os_pid.
-
--type port_info_result_item() ::
- {registered_name, RegName :: atom()} |
- {id, Index :: non_neg_integer()} |
- {connected, Pid :: pid()} |
- {links, Pids :: [pid()]} |
- {name, String :: string()} |
- {input, Bytes :: non_neg_integer()} |
- {output, Bytes :: non_neg_integer()} |
- {os_pid, OsPid :: non_neg_integer() | 'undefined'}.
-
-%% Shadowed by erl_bif_types: erlang:port_info/1
--spec erlang:port_info(Port) -> Result when
- Port :: port() | atom(),
- Result :: [port_info_result_item()] | undefined.
-port_info(_Result) ->
- erlang:nif_error(undefined).
-
-%% Shadowed by erl_bif_types: erlang:port_info/2
--spec erlang:port_info(Port, Item) -> Result when
- Port :: port() | atom(),
- Item :: port_info_item(),
- Result :: port_info_result_item() | undefined.
-port_info(_Result, _Item) ->
- erlang:nif_error(undefined).
-
-type priority_level() ::
low | normal | high | max.
@@ -1836,7 +1756,7 @@ process_flag(_Flag, _Value) ->
{group_leader, GroupLeader :: pid()} |
{heap_size, Size :: non_neg_integer()} |
{initial_call, mfa()} |
- {links, Pids :: [pid()]} |
+ {links, PidsAndPorts :: [pid() | port()]} |
{last_calls, false | (Calls :: [mfa()])} |
{memory, Size :: non_neg_integer()} |
{message_que_len, MessageQueueLen :: non_neg_integer()} |
@@ -2530,6 +2450,216 @@ suspend_process(P) ->
end.
%%
+%% Port BIFs
+%%
+%% Currently all port BIFs calls the corresponding
+%% erts_internal:port_*() native function which perform
+%% most of the actual work. These native functions should
+%% *never* be called directly by other functionality. The
+%% native functions may be changed, or removed without any
+%% notice whatsoever!
+%%
+%% IMPORTANT NOTE:
+%% When the erts_internal:port_*() native functions return
+%% a reference, they have also internally prepared the
+%% message queue of the caller for a receive that will
+%% unconditionally wait for a message containing this
+%% reference. If the erlang code calling these native
+%% functions do not do this, subsequent receives will not
+%% work as expected! That is, it is of *vital importance*
+%% that the receive is performed as described above!
+%%
+
+-spec port_command(Port, Data) -> 'true' when
+ Port :: port() | atom(),
+ Data :: iodata().
+
+port_command(Port, Data) ->
+ case case erts_internal:port_command(Port, Data, []) of
+ Ref when erlang:is_reference(Ref) -> receive {Ref, Res} -> Res end;
+ Res -> Res
+ end of
+ true -> true;
+ Error -> erlang:error(Error, [Port, Data])
+ end.
+
+-spec port_command(Port, Data, OptionList) -> boolean() when
+ Port :: port() | atom(),
+ Data :: iodata(),
+ Option :: force | nosuspend,
+ OptionList :: [Option].
+
+port_command(Port, Data, Flags) ->
+ case case erts_internal:port_command(Port, Data, Flags) of
+ Ref when erlang:is_reference(Ref) -> receive {Ref, Res} -> Res end;
+ Res -> Res
+ end of
+ Bool when Bool == true; Bool == false -> Bool;
+ Error -> erlang:error(Error, [Port, Data, Flags])
+ end.
+
+-spec port_connect(Port, Pid) -> 'true' when
+ Port :: port() | atom(),
+ Pid :: pid().
+
+port_connect(Port, Pid) ->
+ case case erts_internal:port_connect(Port, Pid) of
+ Ref when erlang:is_reference(Ref) -> receive {Ref, Res} -> Res end;
+ Res -> Res
+ end of
+ true -> true;
+ Error -> erlang:error(Error, [Port, Pid])
+ end.
+
+-spec port_close(Port) -> 'true' when
+ Port :: port() | atom().
+
+port_close(Port) ->
+ case case erts_internal:port_close(Port) of
+ Ref when erlang:is_reference(Ref) -> receive {Ref, Res} -> Res end;
+ Res -> Res
+ end of
+ true -> true;
+ Error -> erlang:error(Error, [Port])
+ end.
+
+-spec port_control(Port, Operation, Data) -> iodata() | binary() when
+ Port :: port() | atom(),
+ Operation :: integer(),
+ Data :: iodata().
+
+port_control(Port, Operation, Data) ->
+ case case erts_internal:port_control(Port, Operation, Data) of
+ Ref when erlang:is_reference(Ref) -> receive {Ref, Res} -> Res end;
+ Res -> Res
+ end of
+ badarg -> erlang:error(badarg, [Port, Operation, Data]);
+ Result -> Result
+ end.
+
+-spec erlang:port_call(Port, Data) -> term() when
+ Port :: port() | atom(),
+ Data :: term().
+
+port_call(Port, Data) ->
+ case case erts_internal:port_call(Port, 0, Data) of
+ Ref when erlang:is_reference(Ref) -> receive {Ref, Res} -> Res end;
+ Res -> Res
+ end of
+ {ok, Result} -> Result;
+ Error -> erlang:error(Error, [Port, Data])
+ end.
+
+-spec erlang:port_call(Port, Operation, Data) -> term() when
+ Port :: port() | atom(),
+ Operation :: integer(),
+ Data :: term().
+
+port_call(Port, Operation, Data) ->
+ case case erts_internal:port_call(Port, Operation, Data) of
+ Ref when erlang:is_reference(Ref) -> receive {Ref, Res} -> Res end;
+ Res -> Res
+ end of
+ {ok, Result} -> Result;
+ Error -> erlang:error(Error, [Port, Operation, Data])
+ end.
+
+-spec erlang:port_info(Port) -> Result when
+ Port :: port() | atom(),
+ ResultItem :: {registered_name, RegisteredName :: atom()}
+ | {id, Index :: non_neg_integer()}
+ | {connected, Pid :: pid()}
+ | {links, Pids :: [pid()]}
+ | {name, String :: string()}
+ | {input, Bytes :: non_neg_integer()}
+ | {output, Bytes :: non_neg_integer()}
+ | {os_pid, OsPid :: non_neg_integer() | 'undefined'},
+ Result :: [ResultItem] | 'undefined'.
+
+port_info(Port) ->
+ case case erts_internal:port_info(Port) of
+ Ref when erlang:is_reference(Ref) -> receive {Ref, Res} -> Res end;
+ Res -> Res
+ end of
+ badarg -> erlang:error(badarg, [Port]);
+ Result -> Result
+ end.
+
+-spec erlang:port_info(Port, connected) -> {connected, Pid} | 'undefined' when
+ Port :: port() | atom(),
+ Pid :: pid();
+ (Port, id) -> {id, Index} | 'undefined' when
+ Port :: port() | atom(),
+ Index :: non_neg_integer();
+ (Port, input) -> {input, Bytes} | 'undefined' when
+ Port :: port() | atom(),
+ Bytes :: non_neg_integer();
+ (Port, links) -> {links, Pids} | 'undefined' when
+ Port :: port() | atom(),
+ Pids :: [pid()];
+ (Port, locking) -> {locking, Locking} | 'undefined' when
+ Port :: port() | atom(),
+ Locking :: 'false' | 'port_level' | 'driver_level';
+ (Port, memory) -> {memory, Bytes} | 'undefined' when
+ Port :: port() | atom(),
+ Bytes :: non_neg_integer();
+ (Port, monitors) -> {monitors, Monitors} | 'undefined' when
+ Port :: port() | atom(),
+ Monitors :: [{process, pid()}];
+ (Port, name) -> {name, Name} | 'undefined' when
+ Port :: port() | atom(),
+ Name :: string();
+ (Port, os_pid) -> {os_pid, OsPid} | 'undefined' when
+ Port :: port() | atom(),
+ OsPid :: non_neg_integer() | 'undefined';
+ (Port, output) -> {output, Bytes} | 'undefined' when
+ Port :: port() | atom(),
+ Bytes :: non_neg_integer();
+ (Port, parallelism) -> {parallelism, Boolean} | 'undefined' when
+ Port :: port() | atom(),
+ Boolean :: boolean();
+ (Port, queue_size) -> {queue_size, Bytes} | 'undefined' when
+ Port :: port() | atom(),
+ Bytes :: non_neg_integer();
+ (Port, registered_name) -> {registered_name, RegisteredName} | [] | 'undefined' when
+ Port :: port() | atom(),
+ RegisteredName :: atom().
+
+port_info(Port, Item) ->
+ case case erts_internal:port_info(Port, Item) of
+ Ref when erlang:is_reference(Ref) -> receive {Ref, Res} -> Res end;
+ Res -> Res
+ end of
+ badarg -> erlang:error(badarg, [Port, Item]);
+ Result -> Result
+ end.
+
+-spec erlang:port_set_data(Port, Data) -> 'true' when
+ Port :: port() | atom(),
+ Data :: term().
+
+port_set_data(Port, Data) ->
+ case case erts_internal:port_set_data(Port, Data) of
+ Ref when erlang:is_reference(Ref) -> receive {Ref, Res} -> Res end;
+ Res -> Res
+ end of
+ badarg -> erlang:error(badarg, [Port, Data]);
+ Result -> Result
+ end.
+
+-spec erlang:port_get_data(Port) -> term() when
+ Port :: port() | atom().
+
+port_get_data(Port) ->
+ case case erts_internal:port_get_data(Port) of
+ Ref when erlang:is_reference(Ref) -> receive {Ref, Res} -> Res end;
+ Res -> Res
+ end of
+ {ok, Data} -> Data;
+ Error -> erlang:error(Error, [Port])
+ end.
+
+%%
%% If the emulator wants to perform a distributed command and
%% a connection is not established to the actual node the following
%% functions are called in order to set up the connection and then