summaryrefslogtreecommitdiff
path: root/erts
diff options
context:
space:
mode:
authorBjörn-Egil Dahlberg <egil@erlang.org>2012-03-19 16:25:39 +0100
committerBjörn-Egil Dahlberg <egil@erlang.org>2012-03-19 16:25:39 +0100
commit68ba8d70deb1549dd37a8325eea686c9908f926b (patch)
tree50fbabbf3cb2a52b10fc9a629195baf22b8d17ca /erts
parent662e3ffeed74d9121315d86af46430dd71e01709 (diff)
parent65ba37d1371f36a1666a53c57ac42c73692b8096 (diff)
downloaderlang-68ba8d70deb1549dd37a8325eea686c9908f926b.tar.gz
Merge branch 'ph/fix-enfile/OTP-9990' into maint
* ph/fix-enfile/OTP-9990: Update preloaded prim_inet.beam gen_tcp: Use correct specs for accept and listen prim_inet: Catch system_limit in open_port Fix returned error from gen_tcp:accept/1,2 when running out of ports
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.beambin69980 -> 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 b23b1f628d..fe1a7ba345 100644
--- a/erts/emulator/beam/io.c
+++ b/erts/emulator/beam/io.c
@@ -743,7 +743,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 47a99fdbe6..060d72199d 100644
--- a/erts/emulator/drivers/common/inet_drv.c
+++ b/erts/emulator/drivers/common/inet_drv.c
@@ -553,6 +553,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.
**
@@ -1645,6 +1651,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)
@@ -1665,13 +1682,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)
@@ -1683,14 +1696,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));
}
@@ -8051,7 +8057,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)
@@ -8090,7 +8096,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 f382236af7..b2f3ab6c5b 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;