summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukas Larsson <lukas@erlang.org>2021-02-22 14:20:58 +0100
committerLukas Larsson <lukas@erlang.org>2021-03-03 08:44:08 +0100
commit139f915bded4218043b670d08eb0bd35f9a5d63e (patch)
tree2352641101f25075dfafeabaae933fa751942fc3
parent7fe7fa3dde556b5b92522f8279d465bb52baf1f6 (diff)
downloaderlang-139f915bded4218043b670d08eb0bd35f9a5d63e.tar.gz
erts: Fix fd leak when an active socket is closed remotely
Fixes #4540
-rw-r--r--erts/emulator/drivers/common/inet_drv.c27
1 files changed, 17 insertions, 10 deletions
diff --git a/erts/emulator/drivers/common/inet_drv.c b/erts/emulator/drivers/common/inet_drv.c
index b71ce0389d..e4fc0d1a6b 100644
--- a/erts/emulator/drivers/common/inet_drv.c
+++ b/erts/emulator/drivers/common/inet_drv.c
@@ -9922,6 +9922,15 @@ static void tcp_inet_stop(ErlDrvData e)
tcp_close_check(desc);
tcp_clear_input(desc);
+#ifdef HAVE_SENDFILE
+ if(desc->tcp_add_flags & TCP_ADDF_SENDFILE) {
+ desc->tcp_add_flags &= ~TCP_ADDF_SENDFILE;
+ close(desc->sendfile.dup_file_fd);
+ DEBUGF(("tcp_inet_stop(%p): SENDFILE dup closed %d\r\n",
+ desc->inet.port, desc->sendfile.dup_file_fd));
+ }
+#endif
+
DEBUGF(("tcp_inet_stop(%ld) }\r\n", (long)desc->inet.port));
inet_stop(INETP(desc));
}
@@ -9937,12 +9946,6 @@ static void tcp_inet_stop(ErlDrvData e)
* will be freed through tcp_inet_stop later on. */
static void tcp_desc_close(tcp_descriptor* desc)
{
-#ifdef HAVE_SENDFILE
- if(desc->tcp_add_flags & TCP_ADDF_SENDFILE) {
- desc->tcp_add_flags &= ~TCP_ADDF_SENDFILE;
- close(desc->sendfile.dup_file_fd);
- }
-#endif
tcp_clear_input(desc);
tcp_clear_output(desc);
@@ -10315,6 +10318,9 @@ static ErlDrvSSizeT tcp_inet_ctl(ErlDrvData e, unsigned int cmd,
desc->sendfile.dup_file_fd = dup(raw_file_fd);
+ DEBUGF(("tcp_inet_ctl(%p): SENDFILE dup %d\r\n",
+ desc->inet.port, desc->sendfile.dup_file_fd));
+
if(desc->sendfile.dup_file_fd == -1) {
return ctl_error(errno, rbuf, rsize);
}
@@ -10492,11 +10498,9 @@ static void tcp_inet_flush(ErlDrvData e)
#ifdef HAVE_SENDFILE
/* The old file driver aborted when it was stopped during sendfile, so
- * we'll clear the flag and discard all output. */
+ * we'll clear the flag and discard all output. It is the job of
+ * tcp_inet_stop to close the extra sendfile fd. */
if(desc->tcp_add_flags & TCP_ADDF_SENDFILE) {
- desc->tcp_add_flags &= ~TCP_ADDF_SENDFILE;
- close(desc->sendfile.dup_file_fd);
-
discard_output = 1;
}
#endif
@@ -11634,6 +11638,9 @@ static int tcp_sendfile_completed(tcp_descriptor* desc) {
desc->tcp_add_flags &= ~TCP_ADDF_SENDFILE;
close(desc->sendfile.dup_file_fd);
+ DEBUGF(("tcp_sendfile_completed(%p): SENDFILE dup closed %d\r\n",
+ desc->inet.port, desc->sendfile.dup_file_fd));
+
/* While we flushed the output queue prior to sending the file, we've
* deferred clearing busy status until now as there's no point in doing so
* while we still have a file to send.