Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Lib/multiprocessing/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ def arbitrary_address(family):
if family == 'AF_INET':
return ('localhost', 0)
elif family == 'AF_UNIX':
return tempfile.mktemp(prefix='listener-', dir=util.get_temp_dir())
return tempfile.mktemp(prefix='sock-', dir=util.get_temp_dir())
elif family == 'AF_PIPE':
return tempfile.mktemp(prefix=r'\\.\pipe\pyc-%d-%d-' %
(os.getpid(), next(_mmap_counter)), dir="")
Expand Down
36 changes: 35 additions & 1 deletion Lib/multiprocessing/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,21 @@ def is_abstract_socket_namespace(address):
# Function returning a temp directory which will be removed on exit
#

# Maximum length of a socket file path is usually between 92 and 108 [1].
# BSD-based operating systems usually use 104 (OpenBSD, FreeBSD, macOS)
# and Linux uses 108 [2].
#
# [1]: https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/sys_un.h.html
# [2]: https://man7.org/linux/man-pages/man7/unix.7.html.

if sys.platform == 'linux':
_SUN_PATH_MAX = 104
elif sys.platform.startswith(('openbsd', 'freebsd')):
_SUN_PATH_MAX = 108
else:
# On Windows platforms, we do not create AF_UNIX sockets.
_SUN_PATH_MAX = None if os.name == 'nt' else 92

def _remove_temp_dir(rmtree, tempdir):
rmtree(tempdir)

Expand All @@ -135,7 +150,26 @@ def get_temp_dir():
tempdir = process.current_process()._config.get('tempdir')
if tempdir is None:
import shutil, tempfile
tempdir = tempfile.mkdtemp(prefix='pymp-')
if os.name == 'nt':
tempdir = tempfile.mkdtemp(prefix='pymp-')
else:
# Most of the time, the root temporary directory is /tmp, and thus
# listener sockets files "$TMPDIR/pymp-XXXXXXXX/sock-XXXXXXXX"
# do not have a path length exceeding SUN_PATH_MAX.
#
# If users specify their own temporary directory, we may be unable
# to create those files. Therefore, we fall back to the system-wide
# temporary directory /tmp, assumed to exist on POSIX systems.
#
# See https://github.com/python/cpython/issues/132124.
base_tempdir = tempfile.gettempdir()
# len(base_tempdir) + len('/pymp-XXXXXXXX') + len('/sock-XXXXXXXX')
sun_path_len = len(base_tempdir) + 14 + 14
if sun_path_len > _SUN_PATH_MAX:
# fallback to the system-wide temporary directory,
# ignoring environment variables.
base_tempdir = '/tmp'
tempdir = tempfile.mkdtemp(prefix='pymp-', dir=base_tempdir)
info('created temp directory %s', tempdir)
# keep a strong reference to shutil.rmtree(), since the finalizer
# can be called late during Python shutdown
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
On POSIX-compliant systems, :func:`!multiprocessing.util.get_temp_dir` now
ignores :envvar:`TMPDIR` (and similar environment variables) if the path
length of ``AF_UNIX`` socket files exceeds the platform-specific maximum
length when using the :ref:`forkserver
<multiprocessing-start-method-forkserver>` start method. Patch by Bénédikt
Tran.
Loading