aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMicael Karlberg <[email protected]>2018-04-09 12:54:52 +0200
committerMicael Karlberg <[email protected]>2018-09-18 13:01:37 +0200
commit9e6fda01b1af0c42cee9f983d5bddecc7eb7e240 (patch)
treef452ccfc553ada516a53947f6e62fe0f0d584347
parente752b4a8187903da609004c56f0f019b1d7b7605 (diff)
downloadotp-9e6fda01b1af0c42cee9f983d5bddecc7eb7e240.tar.gz
otp-9e6fda01b1af0c42cee9f983d5bddecc7eb7e240.tar.bz2
otp-9e6fda01b1af0c42cee9f983d5bddecc7eb7e240.zip
[socket-nif] Completed listen
-rw-r--r--erts/emulator/nifs/common/socket_nif.c58
-rw-r--r--erts/preloaded/src/socket.erl32
2 files changed, 77 insertions, 13 deletions
diff --git a/erts/emulator/nifs/common/socket_nif.c b/erts/emulator/nifs/common/socket_nif.c
index a702e35a0d..88fb2206e4 100644
--- a/erts/emulator/nifs/common/socket_nif.c
+++ b/erts/emulator/nifs/common/socket_nif.c
@@ -322,6 +322,7 @@ typedef unsigned long long llu_t;
#define sock_getopt(s,t,n,v,l) getsockopt((s),(t),(n),(v),(l))
#define sock_htons(x) htons((x))
#define sock_htonl(x) htonl((x))
+#define sock_listen(s, b) listen((s), (b))
#define sock_name(s, addr, len) getsockname((s), (addr), (len))
#define sock_open(domain, type, proto) \
make_noninheritable_handle(socket((domain), (type), (proto)))
@@ -341,6 +342,7 @@ static unsigned long one_value = 1;
#define sock_getopt(s,t,n,v,l) getsockopt((s),(t),(n),(v),(l))
#define sock_htons(x) htons((x))
#define sock_htonl(x) htonl((x))
+#define sock_listen(s, b) listen((s), (b))
#define sock_name(s, addr, len) getsockname((s), (addr), (len))
#define sock_open(domain, type, proto) socket((domain), (type), (proto))
@@ -551,6 +553,9 @@ static ERL_NIF_TERM nconnect(ErlNifEnv* env,
SocketDescriptor* descP,
const ERL_NIF_TERM* addr,
int port);
+static ERL_NIF_TERM nlisten(ErlNifEnv* env,
+ SocketDescriptor* descP,
+ int backlog);
static ERL_NIF_TERM nfinalize_connection(ErlNifEnv* env,
SocketDescriptor* descP);
@@ -1611,6 +1616,59 @@ BOOLEAN_T verify_is_connected(SocketDescriptor* descP, int* err)
/* ----------------------------------------------------------------------
+ * nif_listen
+ *
+ * Description:
+ * Listen for connections on a socket.
+ *
+ * Arguments:
+ * Socket (ref) - Points to the socket descriptor.
+ * Backlog - The maximum length to which the queue of pending
+ * connections for socket may grow.
+ */
+static
+ERL_NIF_TERM nif_listen(ErlNifEnv* env,
+ int argc,
+ const ERL_NIF_TERM argv[])
+{
+ SocketDescriptor* descP;
+ int backlog;
+
+ /* Extract arguments and perform preliminary validation */
+
+ if ((argc != 2) ||
+ !enif_get_resource(env, argv[0], sockets, (void**) &descP) ||
+ !GET_INT(env, argv[1], &backlog)) {
+ return enif_make_badarg(env);
+ }
+
+ return nlisten(env, descP, backlog);
+}
+
+
+
+static
+ERL_NIF_TERM nlisten(ErlNifEnv* env,
+ SocketDescriptor* descP,
+ int backlog)
+{
+ if (descP->state == SOCKET_STATE_CLOSED)
+ return make_error(env, atom_exbadstate);
+
+ if (!IS_OPEN(descP))
+ return make_error(env, atom_exbadstate);
+
+ if (IS_SOCKET_ERROR(sock_listen(descP->sock, backlog)))
+ return make_error2(env, sock_errno());
+
+ descP->state = SOCKET_STATE_LISTENING;
+
+ return atom_ok;
+}
+
+
+
+/* ----------------------------------------------------------------------
* U t i l i t y F u n c t i o n s
* ----------------------------------------------------------------------
*/
diff --git a/erts/preloaded/src/socket.erl b/erts/preloaded/src/socket.erl
index f8e3d0419a..0886c0d211 100644
--- a/erts/preloaded/src/socket.erl
+++ b/erts/preloaded/src/socket.erl
@@ -213,7 +213,10 @@ info() ->
%%
%% ===========================================================================
+%% ===========================================================================
+%%
%% open - create an endpoint for communication
+%%
open(Domain, Type) ->
open(Domain, Type, null).
@@ -272,7 +275,10 @@ default_protocol(null, Type) -> throw({error, {no_default_protocol, Type}})
default_protocol(Protocol, _) -> Protocol.
+%% ===========================================================================
+%%
%% bind - bind a name to a socket
+%%
-spec bind(Socket, FileOrAddr) -> ok | {error, Reason} when
Socket :: socket(),
@@ -318,7 +324,11 @@ bind({socket, _, SockRef}, Addr, Port)
nif_bind(SockRef, {Addr, Port}).
+
+%% ===========================================================================
+%%
%% connect - initiate a connection on a socket
+%%
-spec connect(Socket, Addr, Port) -> ok | {error, Reason} when
Socket :: socket(),
@@ -364,7 +374,11 @@ connect({socket, _, SockRef}, Addr, Port, Timeout)
end.
+
+%% ===========================================================================
+%%
%% listen - listen for connections on a socket
+%%
-spec listen(Socket, Backlog) -> ok | {error, Reason} when
Socket :: socket(),
@@ -375,13 +389,15 @@ listen(Socket) ->
listen(Socket, ?SOCKET_LISTEN_BACKLOG_DEFAULT).
listen({socket, _, SockRef}, Backlog)
- when (is_integer(Backlog) andalso (Backlog >= 0)) orelse is_boolean(Backlog) ->
- EBacklog = enc_backlog(Backlog),
- nif_listen(SockRef, EBacklog).
+ when (is_integer(Backlog) andalso (Backlog >= 0)) ->
+ nif_listen(SockRef, Backlog).
+%% ===========================================================================
+%%
%% accept, accept4 - accept a connection on a socket
+%%
-spec accept(LSocket, Timeout) -> {ok, Socket} | {error, Reason} when
LSocket :: socket(),
@@ -682,16 +698,6 @@ enc_protocol(seqpacket, sctp) -> ?SOCKET_PROTOCOL_SCTP;
enc_protocol(Type, Proto) -> throw({error, {invalid_protocol, {Type, Proto}}}).
--spec enc_backlog(Backlog) -> non_neg_integer() when
- Backlog :: non_neg_integer() | boolean().
-
-enc_backlog(true) ->
- ?SOCKET_LISTEN_BACKLOG_DEFAULT;
-enc_backlog(false) ->
- 0;
-enc_backlog(Backlog) when is_integer(Backlog) andalso (Backlog >= 0) ->
- Backlog.
-
-spec enc_accept_flags(Flags) -> non_neg_integer() when
Flags :: accept_flags().