Skip to content

Commit 53f02f5

Browse files
committed
ensure that we can create AF_UNIX socket files
1 parent 7a504b3 commit 53f02f5

File tree

2 files changed

+36
-2
lines changed

2 files changed

+36
-2
lines changed

Lib/multiprocessing/connection.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ def arbitrary_address(family):
7676
if family == 'AF_INET':
7777
return ('localhost', 0)
7878
elif family == 'AF_UNIX':
79-
return tempfile.mktemp(prefix='listener-', dir=util.get_temp_dir())
79+
return tempfile.mktemp(prefix='sock-', dir=util.get_temp_dir())
8080
elif family == 'AF_PIPE':
8181
return tempfile.mktemp(prefix=r'\\.\pipe\pyc-%d-%d-' %
8282
(os.getpid(), next(_mmap_counter)), dir="")

Lib/multiprocessing/util.py

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,21 @@ def is_abstract_socket_namespace(address):
121121
# Function returning a temp directory which will be removed on exit
122122
#
123123

124+
# Maximum length of a socket file path is usually between 92 and 108 [1].
125+
# BSD-based operating systems usually use 104 (OpenBSD, FreeBSD, macOS)
126+
# and Linux uses 108 [2].
127+
#
128+
# [1]: https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/sys_un.h.html
129+
# [2]: https://man7.org/linux/man-pages/man7/unix.7.html.
130+
131+
if sys.platform == 'linux':
132+
_SUN_PATH_MAX = 104
133+
elif sys.platform.startswith(('openbsd', 'freebsd')):
134+
_SUN_PATH_MAX = 108
135+
else:
136+
# On Windows platforms, we do not create AF_UNIX sockets.
137+
_SUN_PATH_MAX = None if os.name == 'nt' else 92
138+
124139
def _remove_temp_dir(rmtree, tempdir):
125140
rmtree(tempdir)
126141

@@ -135,7 +150,26 @@ def get_temp_dir():
135150
tempdir = process.current_process()._config.get('tempdir')
136151
if tempdir is None:
137152
import shutil, tempfile
138-
tempdir = tempfile.mkdtemp(prefix='pymp-')
153+
if os.name == 'nt':
154+
tempdir = tempfile.mkdtemp(prefix='pymp-')
155+
else:
156+
# Most of the time, the root temporary directory is /tmp, and thus
157+
# listener sockets files "$TMPDIR/pymp-XXXXXXXX/sock-XXXXXXXX"
158+
# do not have a path length exceeding SUN_PATH_MAX.
159+
#
160+
# If users specify their own temporary directory, we may be unable
161+
# to create those files. Therefore, we fall back to the system-wide
162+
# temporary directory /tmp, assumed to exist on POSIX systems.
163+
#
164+
# See https://github.com/python/cpython/issues/132124.
165+
base_tempdir = tempfile.gettempdir()
166+
# len(base_tempdir) + len('/pymp-XXXXXXXX') + len('/sock-XXXXXXXX')
167+
sun_path_len = len(base_tempdir) + 14 + 14
168+
if sun_path_len > _SUN_PATH_MAX:
169+
# fallback to the system-wide temporary directory,
170+
# ignoring environment variables.
171+
base_tempdir = '/tmp'
172+
tempdir = tempfile.mkdtemp(prefix='pymp-', dir=base_tempdir)
139173
info('created temp directory %s', tempdir)
140174
# keep a strong reference to shutil.rmtree(), since the finalizer
141175
# can be called late during Python shutdown

0 commit comments

Comments
 (0)