gh-111246: Remove listening Unix socket on close (#111483)

Try to clean up the socket file we create so we don't add unused noise to the file system.
This commit is contained in:
Pierre Ossman (ThinLinc team) 2023-11-08 17:10:10 +01:00 committed by GitHub
parent f88caab467
commit 74b868f636
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 126 additions and 2 deletions

View file

@ -64,6 +64,7 @@ class _UnixSelectorEventLoop(selector_events.BaseSelectorEventLoop):
def __init__(self, selector=None):
super().__init__(selector)
self._signal_handlers = {}
self._unix_server_sockets = {}
def close(self):
super().close()
@ -284,7 +285,7 @@ class _UnixSelectorEventLoop(selector_events.BaseSelectorEventLoop):
sock=None, backlog=100, ssl=None,
ssl_handshake_timeout=None,
ssl_shutdown_timeout=None,
start_serving=True):
start_serving=True, cleanup_socket=True):
if isinstance(ssl, bool):
raise TypeError('ssl argument must be an SSLContext or None')
@ -340,6 +341,15 @@ class _UnixSelectorEventLoop(selector_events.BaseSelectorEventLoop):
raise ValueError(
f'A UNIX Domain Stream Socket was expected, got {sock!r}')
if cleanup_socket:
path = sock.getsockname()
# Check for abstract socket. `str` and `bytes` paths are supported.
if path[0] not in (0, '\x00'):
try:
self._unix_server_sockets[sock] = os.stat(path).st_ino
except FileNotFoundError:
pass
sock.setblocking(False)
server = base_events.Server(self, [sock], protocol_factory,
ssl, backlog, ssl_handshake_timeout,
@ -460,6 +470,27 @@ class _UnixSelectorEventLoop(selector_events.BaseSelectorEventLoop):
self.remove_writer(fd)
fut.add_done_callback(cb)
def _stop_serving(self, sock):
# Is this a unix socket that needs cleanup?
if sock in self._unix_server_sockets:
path = sock.getsockname()
else:
path = None
super()._stop_serving(sock)
if path is not None:
prev_ino = self._unix_server_sockets[sock]
del self._unix_server_sockets[sock]
try:
if os.stat(path).st_ino == prev_ino:
os.unlink(path)
except FileNotFoundError:
pass
except OSError as err:
logger.error('Unable to clean up listening UNIX socket '
'%r: %r', path, err)
class _UnixReadPipeTransport(transports.ReadTransport):