@@ -143,6 +143,41 @@ def is_abstract_socket_namespace(address):
143143 # On Windows platforms, we do not create AF_UNIX sockets.
144144 _SUN_PATH_MAX = None if os .name == 'nt' else 92
145145
146+ # The temporary socket file path (without NULL terminator) is
147+ #
148+ # TEMPDIR/{_TMPPYMP_PREFIX}{S1}/{_TMPSOCK_PREFIX}{S2}
149+ #
150+ # where
151+ #
152+ # - S1 is a random suffix of length 8 generated by get_temp_dir().
153+ # This is used to generate the temporary sub-directory that will
154+ # contains the socket file. Update _TMPPYMP_SUFFIXLEN accordingly
155+ # if the random suffix length chosen by tempfile.mkdtemp() changes.
156+ #
157+ # - S2 is a random suffix of length 2N generated by os.urandom(N).hex()
158+ # in multiprocessing.connection.arbitrary_address(). The value of N
159+ # is not fixed and may vary across Python versions as to minimize
160+ # collisions and path lengths.
161+ #
162+ _TMPPYMP_PREFIX = "pymp-"
163+ _TMPPYMP_PREFIXLEN = len (_TMPPYMP_PREFIX )
164+ _TMPPYMP_SUFFIXLEN = 8
165+ _TMPSOCK_PREFIX = "sock-"
166+ _TMPSOCK_PREFIXLEN = len (_TMPSOCK_PREFIX )
167+ _TMPSOCK_SUFFIXLEN = 12
168+
169+ # Length of the socket filepath from the chosen temporary directory,
170+ # including a leading path separator and the path separator between
171+ # the temporary subdirectory and the socket filename.
172+ _SUN_PATH_LEN_RESERVED = (
173+ len (os .path .sep ) + _TMPPYMP_PREFIXLEN + _TMPPYMP_SUFFIXLEN +
174+ len (os .path .sep ) + _TMPSOCK_PREFIXLEN + _TMPSOCK_SUFFIXLEN
175+ )
176+ assert (
177+ _SUN_PATH_MAX is None
178+ or _SUN_PATH_LEN_RESERVED < _SUN_PATH_MAX
179+ )
180+
146181
147182def _remove_temp_dir (rmtree , tempdir ):
148183 rmtree (tempdir )
@@ -161,24 +196,16 @@ def _get_base_temp_dir(tempfile):
161196 """
162197 if os .name == 'nt' :
163198 return None
164- # Most of the time, the default temporary directory is /tmp. Thus,
165- # listener sockets files "$TMPDIR/pymp-XXXXXXXX/sock-XXXXXXXX" do
166- # not have a path length exceeding SUN_PATH_MAX.
199+ # Most of the time, the default temporary directory is /tmp. As such,
200+ # the path length of listener sockets files does not exceed SUN_PATH_MAX.
167201 #
168202 # If users specify their own temporary directory, we may be unable
169203 # to create those files. Therefore, we fall back to the system-wide
170204 # temporary directory /tmp, assumed to exist on POSIX systems.
171205 #
172206 # See https://github.com/python/cpython/issues/132124.
173207 base_tempdir = tempfile .gettempdir ()
174- # Files created in a temporary directory are suffixed by a string
175- # generated by tempfile._RandomNameSequence, which, by design,
176- # is 8 characters long.
177- #
178- # Thus, the socket file path length (without NULL terminator) will be:
179- #
180- # len(base_tempdir + '/pymp-XXXXXXXX' + '/sock-XXXXXXXX')
181- sun_path_len = len (base_tempdir ) + 14 + 14
208+ sun_path_len = len (base_tempdir ) + _SUN_PATH_LEN_RESERVED
182209 # Strict inequality to account for the NULL terminator.
183210 # See https://github.com/python/cpython/issues/140734.
184211 if sun_path_len < _SUN_PATH_MAX :
@@ -206,8 +233,8 @@ def _get_base_temp_dir(tempfile):
206233 # not be able to write socket files out there.
207234 return base_tempdir
208235 warn ("Ignoring user-defined temporary directory: %s" , base_tempdir )
209- # at most max(map(len, dirlist)) + 14 + 14 = 36 characters
210- assert len (base_system_tempdir ) + 14 + 14 < _SUN_PATH_MAX
236+ # The following assertion must be satisfied with the chosen constants.
237+ assert len (base_system_tempdir ) + _SUN_PATH_LEN_RESERVED < _SUN_PATH_MAX
211238 return base_system_tempdir
212239
213240
@@ -218,7 +245,7 @@ def get_temp_dir():
218245 # Deferred until first use to keep importing this module cheap.
219246 import shutil , tempfile
220247 base_tempdir = _get_base_temp_dir (tempfile )
221- tempdir = tempfile .mkdtemp (prefix = 'pymp-' , dir = base_tempdir )
248+ tempdir = tempfile .mkdtemp (prefix = _TMPPYMP_PREFIX , dir = base_tempdir )
222249 info ('created temp directory %s' , tempdir )
223250 # keep a strong reference to shutil.rmtree(), since the finalizer
224251 # can be called late during Python shutdown
0 commit comments