Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 21ff6be

Browse files
committed
gh-111246: Remove listening Unix socket on close (#111246)
Try to clean up the socket file we create so we don't add unused noise to the file system.
1 parent 9a2f2f4 commit 21ff6be

File tree

5 files changed

+63
-0
lines changed

5 files changed

+63
-0
lines changed

Doc/library/asyncio-eventloop.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -800,6 +800,11 @@ Creating network servers
800800

801801
Added the *ssl_shutdown_timeout* parameter.
802802

803+
.. versionchanged:: 3.13
804+
805+
The Unix socket will automatically be removed from the filesystem
806+
when the server is closed.
807+
803808

804809
.. coroutinemethod:: loop.connect_accepted_socket(protocol_factory, \
805810
sock, *, ssl=None, ssl_handshake_timeout=None, \

Doc/whatsnew/3.13.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,12 @@ array
144144
It can be used instead of ``'u'`` type code, which is deprecated.
145145
(Contributed by Inada Naoki in :gh:`80480`.)
146146

147+
asyncio
148+
-------
149+
150+
* :meth:`asyncio.loop.create_unix_server` will now automatically remove
151+
the Unix socket when the server is closed.
152+
147153
copy
148154
----
149155

Lib/asyncio/unix_events.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,27 @@ def cb(fut):
460460
self.remove_writer(fd)
461461
fut.add_done_callback(cb)
462462

463+
def _stop_serving(self, sock):
464+
# Is this a unix socket that needs cleanup?
465+
if sock.family == socket.AF_UNIX:
466+
path = sock.getsockname()
467+
if path == '':
468+
path = None
469+
# Check for abstract socket. `str` and `bytes` paths are supported.
470+
elif path[0] in (0, '\x00'):
471+
path = None
472+
else:
473+
path = None
474+
475+
super()._stop_serving(sock)
476+
477+
if path is not None:
478+
try:
479+
os.unlink(path)
480+
except OSError as err:
481+
logger.error('Unable to clean up listening UNIX socket '
482+
'%r: %r', path, err)
483+
463484

464485
class _UnixReadPipeTransport(transports.ReadTransport):
465486

Lib/test/test_asyncio/test_server.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import asyncio
2+
import os
3+
import socket
24
import time
35
import threading
46
import unittest
@@ -147,6 +149,33 @@ async def serve(*args):
147149
await task2
148150

149151

152+
class UnixServerCleanupTests(unittest.IsolatedAsyncioTestCase):
153+
@socket_helper.skip_unless_bind_unix_socket
154+
async def test_unix_server_addr_cleanup(self):
155+
with test_utils.unix_socket_path() as addr:
156+
async def serve(*args):
157+
pass
158+
159+
srv = await asyncio.start_unix_server(serve, addr)
160+
161+
srv.close()
162+
self.assertFalse(os.path.exists(addr))
163+
164+
@socket_helper.skip_unless_bind_unix_socket
165+
async def test_unix_server_sock_cleanup(self):
166+
with test_utils.unix_socket_path() as addr:
167+
async def serve(*args):
168+
pass
169+
170+
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
171+
sock.bind(addr)
172+
173+
srv = await asyncio.start_unix_server(serve, sock=sock)
174+
175+
srv.close()
176+
self.assertFalse(os.path.exists(addr))
177+
178+
150179
@unittest.skipUnless(hasattr(asyncio, 'ProactorEventLoop'), 'Windows only')
151180
class ProactorStartServerTests(BaseStartServer, unittest.TestCase):
152181

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
:meth:`asyncio.loop.create_unix_server` will now automatically remove the
2+
Unix socket when the server is closed.

0 commit comments

Comments
 (0)