diff options
Diffstat (limited to 'erts/preloaded/src/prim_inet.erl')
-rw-r--r-- | erts/preloaded/src/prim_inet.erl | 56 |
1 files changed, 54 insertions, 2 deletions
diff --git a/erts/preloaded/src/prim_inet.erl b/erts/preloaded/src/prim_inet.erl index 61f727e8a4..2a3605260d 100644 --- a/erts/preloaded/src/prim_inet.erl +++ b/erts/preloaded/src/prim_inet.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2000-2016. All Rights Reserved. +%% Copyright Ericsson AB 2000-2017. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -31,7 +31,7 @@ -export([connect/3, connect/4, async_connect/4]). -export([accept/1, accept/2, async_accept/2]). -export([shutdown/2]). --export([send/2, send/3, sendto/4, sendmsg/3]). +-export([send/2, send/3, sendto/4, sendmsg/3, sendfile/4]). -export([recv/2, recv/3, async_recv/3]). -export([unrecv/2]). -export([recvfrom/2, recvfrom/3]). @@ -500,6 +500,55 @@ sendmsg(S, #sctp_sndrcvinfo{}=SRI, Data) when is_port(S) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% +%% SENDFILE(outsock(), Fd, Offset, Length) -> {ok,BytesSent} | {error, Reason} +%% +%% send Length data bytes from a file handle, to a socket, starting at Offset +%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% "sendfile" is for TCP: + +sendfile(S, FileHandle, Offset, Length) + when not is_port(S); + not is_binary(FileHandle); + not is_integer(Offset); + not is_integer(Length) -> + {error, badarg}; +sendfile(S, FileHandle, Offset, Length) -> + case erlang:port_info(S, connected) of + {connected, Pid} when Pid =:= self() -> + sendfile_1(S, FileHandle, Offset, Length); + {connected, Pid} when Pid =/= self() -> + {error, not_owner}; + _Other -> + {error, einval} + end. + +sendfile_1(S, FileHandle, Offset, 0) -> + sendfile_1(S, FileHandle, Offset, (1 bsl 63) - 1); +sendfile_1(_S, _FileHandle, Offset, Length) when + Offset < 0; Offset > ((1 bsl 63) - 1); + Length < 0; Length > ((1 bsl 63) - 1) -> + {error, einval}; +sendfile_1(S, FileHandle, Offset, Length) -> + Args = [FileHandle, + ?int64(Offset), + ?int64(Length)], + case ctl_cmd(S, ?TCP_REQ_SENDFILE, Args) of + {ok, []} -> + receive + {sendfile, S, {ok, SentLow, SentHigh}} -> + {ok, SentLow bor (SentHigh bsl 32)}; + {sendfile, S, {error, Reason}} -> + {error, Reason}; + {'EXIT', S, _Reason} -> + {error, closed} + end; + {error, Reason} -> + {error, Reason} + end. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% %% RECV(insock(), Length, [Timeout]) -> {ok,Data} | {error, Reason} %% %% receive Length data bytes from a socket @@ -1234,6 +1283,7 @@ enc_opt(netns) -> ?INET_LOPT_NETNS; enc_opt(show_econnreset) -> ?INET_LOPT_TCP_SHOW_ECONNRESET; enc_opt(line_delimiter) -> ?INET_LOPT_LINE_DELIM; enc_opt(raw) -> ?INET_OPT_RAW; +enc_opt(bind_to_device) -> ?INET_OPT_BIND_TO_DEVICE; % Names of SCTP opts: enc_opt(sctp_rtoinfo) -> ?SCTP_OPT_RTOINFO; enc_opt(sctp_associnfo) -> ?SCTP_OPT_ASSOCINFO; @@ -1294,6 +1344,7 @@ dec_opt(?INET_LOPT_NETNS) -> netns; dec_opt(?INET_LOPT_TCP_SHOW_ECONNRESET) -> show_econnreset; dec_opt(?INET_LOPT_LINE_DELIM) -> line_delimiter; dec_opt(?INET_OPT_RAW) -> raw; +dec_opt(?INET_OPT_BIND_TO_DEVICE) -> bind_to_device; dec_opt(I) when is_integer(I) -> undefined. @@ -1395,6 +1446,7 @@ type_opt_1(packet_size) -> uint; type_opt_1(read_packets) -> uint; type_opt_1(netns) -> binary; type_opt_1(show_econnreset) -> bool; +type_opt_1(bind_to_device) -> binary; %% %% SCTP options (to be set). If the type is a record type, the corresponding %% record signature is returned, otherwise, an "elementary" type tag |