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
This commit is contained in:
Roy Williams 2016-10-17 11:33:20 -07:00 committed by Berker Peksag
parent 4416707890
commit b4c41481e2
2 changed files with 9 additions and 3 deletions

View File

@ -25,10 +25,13 @@ class BaseSocket(object):
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 File

@ -6,10 +6,13 @@ except ImportError:
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)