aboutsummaryrefslogtreecommitdiffstats
path: root/erts
diff options
context:
space:
mode:
Diffstat (limited to 'erts')
-rw-r--r--erts/emulator/beam/io.c2
-rw-r--r--erts/emulator/drivers/common/inet_drv.c38
-rw-r--r--erts/preloaded/ebin/prim_inet.beambin69976 -> 70100 bytes
-rw-r--r--erts/preloaded/src/prim_inet.erl6
4 files changed, 27 insertions, 19 deletions
diff --git a/erts/emulator/beam/io.c b/erts/emulator/beam/io.c
index 3deb386621..603a6c47aa 100644
--- a/erts/emulator/beam/io.c
+++ b/erts/emulator/beam/io.c
@@ -744,7 +744,7 @@ driver_create_port(ErlDrvPort creator_port_ix, /* Creating port */
return (ErlDrvTermData) -1; /* pid does not exist */
}
if ((port_num = get_free_port()) < 0) {
- errno = ENFILE;
+ errno = SYSTEM_LIMIT;
erts_smp_proc_unlock(rp, ERTS_PROC_LOCK_LINK);
erts_smp_mtx_unlock(&erts_driver_list_lock);
return (ErlDrvTermData) -1;
diff --git a/erts/emulator/drivers/common/inet_drv.c b/erts/emulator/drivers/common/inet_drv.c
index 608bb5ecaa..e98252e35d 100644
--- a/erts/emulator/drivers/common/inet_drv.c
+++ b/erts/emulator/drivers/common/inet_drv.c
@@ -559,6 +559,12 @@ static int my_strncasecmp(const char *s1, const char *s2, size_t n)
# define VALGRIND_MAKE_MEM_DEFINED(ptr,size)
#endif
+/*
+ Magic errno value used locally for return of {error, system_limit}
+ - the emulator definition of SYSTEM_LIMIT is not available here.
+*/
+#define INET_ERRNO_SYSTEM_LIMIT (15 << 8)
+
/*----------------------------------------------------------------------------
** Interface constants.
**
@@ -1651,6 +1657,17 @@ static struct erl_drv_entry dummy_sctp_driver_entry =
#endif
+/* return lowercase string form of errno value */
+static char *errno_str(int err)
+{
+ switch (err) {
+ case INET_ERRNO_SYSTEM_LIMIT:
+ return "system_limit";
+ default:
+ return erl_errno_id(err);
+ }
+}
+
/* general control reply function */
static ErlDrvSSizeT ctl_reply(int rep, char* buf, ErlDrvSizeT len,
char** rbuf, ErlDrvSizeT rsize)
@@ -1671,13 +1688,9 @@ static ErlDrvSSizeT ctl_reply(int rep, char* buf, ErlDrvSizeT len,
/* general control error reply function */
static ErlDrvSSizeT ctl_error(int err, char** rbuf, ErlDrvSizeT rsize)
{
- char response[256]; /* Response buffer. */
- char* s;
- char* t;
+ char* s = errno_str(err);
- for (s = erl_errno_id(err), t = response; *s; s++, t++)
- *t = tolower(*s);
- return ctl_reply(INET_REP_ERROR, response, t-response, rbuf, rsize);
+ return ctl_reply(INET_REP_ERROR, s, strlen(s), rbuf, rsize);
}
static ErlDrvSSizeT ctl_xerror(char* xerr, char** rbuf, ErlDrvSizeT rsize)
@@ -1689,14 +1702,7 @@ static ErlDrvSSizeT ctl_xerror(char* xerr, char** rbuf, ErlDrvSizeT rsize)
static ErlDrvTermData error_atom(int err)
{
- char errstr[256];
- char* s;
- char* t;
-
- for (s = erl_errno_id(err), t = errstr; *s; s++, t++)
- *t = tolower(*s);
- *t = '\0';
- return driver_mk_atom(errstr);
+ return driver_mk_atom(errno_str(err));
}
@@ -8052,7 +8058,7 @@ static ErlDrvData tcp_inet_start(ErlDrvPort port, char* args)
/* Copy a descriptor, by creating a new port with same settings
* as the descriptor desc.
- * return NULL on error (ENFILE no ports avail)
+ * return NULL on error (SYSTEM_LIMIT no ports avail)
*/
static tcp_descriptor* tcp_inet_copy(tcp_descriptor* desc,SOCKET s,
ErlDrvTermData owner, int* err)
@@ -8091,7 +8097,7 @@ static tcp_descriptor* tcp_inet_copy(tcp_descriptor* desc,SOCKET s,
/* The new port will be linked and connected to the original caller */
port = driver_create_port(port, owner, "tcp_inet", (ErlDrvData) copy_desc);
if ((long)port == -1) {
- *err = ENFILE;
+ *err = INET_ERRNO_SYSTEM_LIMIT;
FREE(copy_desc);
return NULL;
}
diff --git a/erts/preloaded/ebin/prim_inet.beam b/erts/preloaded/ebin/prim_inet.beam
index 23c1d59cd0..49e6c71736 100644
--- a/erts/preloaded/ebin/prim_inet.beam
+++ b/erts/preloaded/ebin/prim_inet.beam
Binary files differ
diff --git a/erts/preloaded/src/prim_inet.erl b/erts/preloaded/src/prim_inet.erl
index 0cedd284db..14bf3b6c69 100644
--- a/erts/preloaded/src/prim_inet.erl
+++ b/erts/preloaded/src/prim_inet.erl
@@ -83,8 +83,10 @@ open(Protocol, Family, Type, Req, Data) ->
end
catch
%% The only (?) way to get here is to try to open
- %% the sctp driver when it does not exist
- error:badarg -> {error,eprotonosupport}
+ %% the sctp driver when it does not exist (badarg)
+ error:badarg -> {error, eprotonosupport};
+ %% system_limit if out of port slots
+ error:system_limit -> {error, system_limit}
end.
enc_family(inet) -> ?INET_AF_INET;