Permalink
Browse files

Fix leak of duplicate file descriptor for bound sockets.

`socket.fromfd` does not close the original file descriptor, so we have to explicitly close it to avoid a leak.

See also:
http://bugs.python.org/issue10099
  • Loading branch information...
rowillia authored and berkerpeksag committed Oct 17, 2016
1 parent 4416707 commit b4c41481e2d5ef127199a4601417a6819053c3fd
Showing with 9 additions and 3 deletions.
  1. +4 −1 gunicorn/sock.py
  2. +5 −2 tests/test_sock.py
View
@@ -25,10 +25,13 @@ def __init__(self, address, conf, log, fd=None):
self.cfg_addr = address
if fd is None:
sock = socket.socket(self.FAMILY, socket.SOCK_STREAM)
+ bound = False
else:
sock = socket.fromfd(fd, self.FAMILY, socket.SOCK_STREAM)
+ os.close(fd)
+ bound = True
- self.sock = self.set_options(sock, bound=(fd is not None))
+ self.sock = self.set_options(sock, bound=bound)
def __str__(self, name):
return "<socket %d>" % self.sock.fileno()
View
@@ -6,10 +6,13 @@
from gunicorn import sock
+@mock.patch('os.close')
@mock.patch('os.getpid')
@mock.patch('os.unlink')
@mock.patch('socket.fromfd')
-def test_unix_socket_close_unlink(fromfd, unlink, getpid):
- gsock = sock.UnixSocket('test.sock', mock.Mock(), mock.Mock(), mock.Mock())
+def test_unix_socket_close_unlink(fromfd, unlink, getpid, close):
+ fd = 42
+ gsock = sock.UnixSocket('test.sock', mock.Mock(), mock.Mock(), fd=fd)
gsock.close()
unlink.assert_called_with("test.sock")
+ close.assert_called_with(fd)

0 comments on commit b4c4148

Please sign in to comment.