diff options
author | Lukas Larsson <lukas@erlang.org> | 2021-02-22 14:20:58 +0100 |
---|---|---|
committer | Lukas Larsson <lukas@erlang.org> | 2021-03-03 08:44:08 +0100 |
commit | 139f915bded4218043b670d08eb0bd35f9a5d63e (patch) | |
tree | 2352641101f25075dfafeabaae933fa751942fc3 | |
parent | 7fe7fa3dde556b5b92522f8279d465bb52baf1f6 (diff) | |
download | erlang-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.c | 27 |
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. |