diff --git a/erts/emulator/drivers/common/inet_drv.c b/erts/emulator/drivers/common/inet_drv.c index 66a5f77d5dc5..d6887e43f66b 100644 --- a/erts/emulator/drivers/common/inet_drv.c +++ b/erts/emulator/drivers/common/inet_drv.c @@ -816,6 +816,7 @@ static size_t my_strnlen(const char *s, size_t maxlen) #define TCP_REQ_UNRECV 43 #define TCP_REQ_SHUTDOWN 44 #define TCP_REQ_SENDFILE 45 +#define TCP_REQ_UNSEND 46 /* UDP and SCTP requests */ #define PACKET_REQ_RECV 60 /* Common for UDP and SCTP */ /* #define SCTP_REQ_LISTEN 61 MERGED Different from TCP; not for UDP */ @@ -11904,6 +11905,25 @@ static ErlDrvSSizeT tcp_inet_ctl(ErlDrvData e, unsigned int cmd, return ctl_reply(INET_REP_OK, NULL, 0, rbuf, rsize); } + case TCP_REQ_UNSEND: { + ErlIOVec iov; + ErlDrvSizeT sz; + + DDBG(INETP(desc), + ("INET-DRV-DBG[%d][" SOCKET_FSTR ",%T] tcp_inet_ctl -> UNSEND\r\n", + __LINE__, desc->inet.s, driver_caller(desc->inet.port)) ); + if (!IS_CONNECTED(INETP(desc))) + return ctl_error(ENOTCONN, rbuf, rsize); + + sz = driver_peekqv(desc->inet.port, &iov); + + if (sz > 0) + { + driver_outputv(desc->inet.port, "?unsend?", sizeof("?unsend?"), &iov, 0); + } + + return ctl_reply(sz?INET_REP_OK:INET_REP_ERROR, NULL, 0, rbuf, rsize); + } case TCP_REQ_SHUTDOWN: { int how; diff --git a/erts/preloaded/ebin/prim_inet.beam b/erts/preloaded/ebin/prim_inet.beam index 883010b373ef..9ef79c0ebc63 100644 Binary files a/erts/preloaded/ebin/prim_inet.beam and b/erts/preloaded/ebin/prim_inet.beam differ diff --git a/erts/preloaded/src/prim_inet.erl b/erts/preloaded/src/prim_inet.erl index a9264d551add..e6e64b44b72c 100644 --- a/erts/preloaded/src/prim_inet.erl +++ b/erts/preloaded/src/prim_inet.erl @@ -34,6 +34,7 @@ -export([send/2, send/3, sendto/4, sendmsg/3, sendfile/4]). -export([recv/2, recv/3, async_recv/3]). -export([unrecv/2]). +-export([unsend/2]). -export([recvfrom/2, recvfrom/3]). -export([setopt/3, setopts/2, getopt/2, getopts/2, is_sockopt_val/2]). -export([chgopt/3, chgopts/2]). @@ -1468,6 +1469,18 @@ unrecv(S, Data) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% +%% UNSEND(insock(), data) -> ok | {error, Reason} +%% +%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +unsend(S, Data) -> + case ctl_cmd(S, ?TCP_REQ_UNSEND, Data) of + {ok, _} -> ok; + {error,_}=Error -> Error + end. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% %% DETACH(insock()) -> ok %% %% unlink from a socket diff --git a/lib/kernel/src/inet_int.hrl b/lib/kernel/src/inet_int.hrl index 2f50f2c23cbd..4d5facde6636 100644 --- a/lib/kernel/src/inet_int.hrl +++ b/lib/kernel/src/inet_int.hrl @@ -102,6 +102,7 @@ -define(TCP_REQ_UNRECV, 43). -define(TCP_REQ_SHUTDOWN, 44). -define(TCP_REQ_SENDFILE, 45). +-define(TCP_REQ_UNSEND, 46). %% UDP and SCTP requests -define(PACKET_REQ_RECV, 60).