Skip to content

Commit

Permalink
Fix clonefile across filesystems (#1737)
Browse files Browse the repository at this point in the history
Fixes #1736
  • Loading branch information
keith authored Oct 14, 2022
1 parent 7712d23 commit 306e300
Showing 1 changed file with 11 additions and 4 deletions.
15 changes: 11 additions & 4 deletions tools/bundletool/bundletool_experimental.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,21 +46,23 @@
bundle is complete but before it is signed.
"""

import errno
import filecmp
import json
import os
import shutil
import sys
import zipfile
from ctypes import cdll, c_char_p, c_int
from ctypes import CDLL, c_char_p, c_int, get_errno

_CLONEFILE = None
_USE_CLONEFILE = sys.platform == "darwin"
def _load_clonefile():
global _CLONEFILE
if _CLONEFILE:
return _CLONEFILE

system = cdll.LoadLibrary('/usr/lib/libSystem.dylib')
system = CDLL('/usr/lib/libSystem.dylib', use_errno=True)
_CLONEFILE = system.clonefile
_CLONEFILE.argtypes = [c_char_p, c_char_p, c_int] # src, dest, flags
_CLONEFILE.restype = c_int # 0 on success
Expand Down Expand Up @@ -212,11 +214,16 @@ def _copy_file(self, src, dest, executable, bundle_root):
raise BundleConflictError(dest)

self._makedirs_safely(os.path.dirname(full_dest))
if sys.platform == "darwin":
global _USE_CLONEFILE
if _USE_CLONEFILE:
clonefile = _load_clonefile()
result = clonefile(src.encode(), full_dest.encode(), 0)
if result != 0:
raise Exception(f"failed to clonefile {src} to {full_dest}")
if get_errno() in (errno.EXDEV, errno.ENOTSUP):
_USE_CLONEFILE = False
shutil.copy(src, full_dest)
else:
raise Exception(f"failed to clonefile {src} to {full_dest}")
else:
shutil.copy(src, full_dest)
os.chmod(full_dest, 0o755 if executable else 0o644)
Expand Down

0 comments on commit 306e300

Please sign in to comment.