@@ -238,25 +238,45 @@ def hash_timestamp(afile):
238238 return md5hex
239239
240240
241- def _on_cifs ( fname ):
242- """ Checks whether a PATH is on a CIFS filesystem mounted in a POSIX
243- host (i.e., has the " mount" command) .
241+ def _generate_cifs_table ( ):
242+ """Construct a reverse-length ordered list of mount points that
243+ fall under a CIFS mount.
244244
245- CIFS shares are how Docker mounts Windows host directories into containers.
246- CIFS has partial support for symlinks that can break, causing misleading
247- errors, so this test is used to disable them on such systems.
245+ This precomputation allows efficient checking for whether a given path
246+ would be on a CIFS filesystem.
247+
248+ On systems without a ``mount`` command, or with no CIFS mounts, returns an
249+ empty list.
248250 """
249251 exit_code , output = subprocess .getstatusoutput ("mount" )
250252 # Not POSIX
251253 if exit_code != 0 :
252- return False
254+ return []
253255
254256 # (path, fstype) tuples, sorted by path length (longest first)
255- paths_types = sorted ((line .split ()[2 :5 :2 ] for line in output .splitlines ()),
257+ mount_info = sorted ((line .split ()[2 :5 :2 ] for line in output .splitlines ()),
256258 key = lambda x : len (x [0 ]),
257- reverse = True )
259+ cifs_paths = [path for path , fstype in mount_info ]
260+ if cifs_paths == []:
261+ return []
262+ 263+ return [mount for mount in mount_info
264+ if any (mount [0 ].startswith (path ) for path in cifs_paths )]
265+ 266+ 267+ _cifs_table = _generate_cifs_table ()
268+ 269+ 270+ def on_cifs (fname ):
271+ """ Checks whether a PATH is on a CIFS filesystem mounted in a POSIX
272+ host (i.e., has the "mount" command).
273+
274+ CIFS shares are how Docker mounts Windows host directories into containers.
275+ CIFS has partial support for symlinks that can break, causing misleading
276+ errors, so this test is used to disable them on such systems.
277+ """
258278 # Only the first match counts
259- for fspath , fstype in paths_types :
279+ for fspath , fstype in _cifs_table :
260280 if fname .startswith (fspath ):
261281 return fstype == 'cifs'
262282 return False
@@ -314,7 +334,7 @@ def copyfile(originalfile, newfile, copy=False, create_new=False,
314334 hashmethod = config .get ('execution' , 'hash_method' ).lower ()
315335
316336 # Don't try creating symlinks on CIFS
317- if _on_cifs (newfile ):
337+ if copy is False and on_cifs (newfile ):
318338 copy = True
319339
320340 # Existing file
0 commit comments