summaryrefslogtreecommitdiffstats
path: root/Lib/asyncio/unix_events.py
diff options
context:
space:
mode:
authorPierre Ossman (ThinLinc team) <ossman@cendio.se>2023-11-08 16:10:10 (GMT)
committerGitHub <noreply@github.com>2023-11-08 16:10:10 (GMT)
commit74b868f636a8af9e5540e3315de666500147d47a (patch)
treee36a68b54fee50c800155c22ba796dcdbaab498c /Lib/asyncio/unix_events.py
parentf88caab467eb57cfe293cdf9fb7cce29b24fda7f (diff)
downloadcpython-74b868f636a8af9e5540e3315de666500147d47a.zip
cpython-74b868f636a8af9e5540e3315de666500147d47a.tar.gz
cpython-74b868f636a8af9e5540e3315de666500147d47a.tar.bz2
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.
Diffstat (limited to 'Lib/asyncio/unix_events.py')
-rw-r--r--Lib/asyncio/unix_events.py33
1 files changed, 32 insertions, 1 deletions
diff --git a/Lib/asyncio/unix_events.py b/Lib/asyncio/unix_events.py
index c944191..41ccf1b 100644
--- a/Lib/asyncio/unix_events.py
+++ b/Lib/asyncio/unix_events.py
@@ -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):