mirror of
https://github.com/9001/copyparty.git
synced 2025-09-28 12:42:26 -06:00
shutil: ignore errors from copystat in copy2;
ntfs on linux can be picky about cloning mtime onto a new file; generally we don't care if that fails, however, we also want the speedup that CopyFile2 can offer, so cannot use copyfile directly this avoids the following issue: up2k:3537 <_symlink>: shutil.copy2(fsenc(csrc), fsenc(dst)) shutil:437 <copy2>: copystat(src, dst, follow_symlinks=follow_sym[...] shutil:376 <copystat>: lookup("utime")(dst, ns=(st.st_atime_ns, s[...] [PermissionError] [Errno 1] Operation not permitted, '/windows/videos'
This commit is contained in:
parent
25749b4b5f
commit
e09f3c9e2c
|
@ -60,6 +60,7 @@ from .util import (
|
||||||
sfsenc,
|
sfsenc,
|
||||||
spack,
|
spack,
|
||||||
statdir,
|
statdir,
|
||||||
|
trystat_shutil_copy2,
|
||||||
ub64enc,
|
ub64enc,
|
||||||
unhumanize,
|
unhumanize,
|
||||||
vjoin,
|
vjoin,
|
||||||
|
@ -2768,7 +2769,7 @@ class Up2k(object):
|
||||||
cur.close()
|
cur.close()
|
||||||
db.close()
|
db.close()
|
||||||
|
|
||||||
shutil.copy2(fsenc(db_path), fsenc(bak))
|
trystat_shutil_copy2(self.log, fsenc(db_path), fsenc(bak))
|
||||||
return self._orz(db_path)
|
return self._orz(db_path)
|
||||||
|
|
||||||
def _read_ver(self, cur: "sqlite3.Cursor") -> Optional[int]:
|
def _read_ver(self, cur: "sqlite3.Cursor") -> Optional[int]:
|
||||||
|
@ -3591,7 +3592,7 @@ class Up2k(object):
|
||||||
t = "BUG: no valid sources to link from! orig(%r) fsrc(%r) link(%r)"
|
t = "BUG: no valid sources to link from! orig(%r) fsrc(%r) link(%r)"
|
||||||
self.log(t, 1)
|
self.log(t, 1)
|
||||||
raise Exception(t % (src, fsrc, dst))
|
raise Exception(t % (src, fsrc, dst))
|
||||||
shutil.copy2(fsenc(csrc), fsenc(dst))
|
trystat_shutil_copy2(self.log, fsenc(csrc), fsenc(dst))
|
||||||
|
|
||||||
if lmod and (not linked or SYMTIME):
|
if lmod and (not linked or SYMTIME):
|
||||||
bos.utime_c(self.log, dst, int(lmod), False)
|
bos.utime_c(self.log, dst, int(lmod), False)
|
||||||
|
@ -4427,7 +4428,7 @@ class Up2k(object):
|
||||||
b1, b2 = fsenc(sabs), fsenc(dabs)
|
b1, b2 = fsenc(sabs), fsenc(dabs)
|
||||||
is_link = os.path.islink(b1) # due to _relink
|
is_link = os.path.islink(b1) # due to _relink
|
||||||
try:
|
try:
|
||||||
shutil.copy2(b1, b2)
|
trystat_shutil_copy2(self.log, b1, b2)
|
||||||
except:
|
except:
|
||||||
try:
|
try:
|
||||||
wunlink(self.log, dabs, dvn.flags)
|
wunlink(self.log, dabs, dvn.flags)
|
||||||
|
@ -4733,7 +4734,7 @@ class Up2k(object):
|
||||||
b1, b2 = fsenc(sabs), fsenc(dabs)
|
b1, b2 = fsenc(sabs), fsenc(dabs)
|
||||||
is_link = os.path.islink(b1) # due to _relink
|
is_link = os.path.islink(b1) # due to _relink
|
||||||
try:
|
try:
|
||||||
shutil.copy2(b1, b2)
|
trystat_shutil_copy2(self.log, b1, b2)
|
||||||
except:
|
except:
|
||||||
try:
|
try:
|
||||||
wunlink(self.log, dabs, dvn.flags)
|
wunlink(self.log, dabs, dvn.flags)
|
||||||
|
|
|
@ -2639,6 +2639,24 @@ def set_fperms(f: Union[typing.BinaryIO, typing.IO[Any]], vf: dict[str, Any]) ->
|
||||||
os.fchown(fno, vf["uid"], vf["gid"])
|
os.fchown(fno, vf["uid"], vf["gid"])
|
||||||
|
|
||||||
|
|
||||||
|
def trystat_shutil_copy2(log: "NamedLogger", src: bytes, dst: bytes) -> bytes:
|
||||||
|
try:
|
||||||
|
return shutil.copy2(src, dst)
|
||||||
|
except:
|
||||||
|
# ignore failed mtime on linux+ntfs; for example:
|
||||||
|
# shutil.py:437 <copy2>: copystat(src, dst, follow_symlinks=follow_symlinks)
|
||||||
|
# shutil.py:376 <copystat>: lookup("utime")(dst, ns=(st.st_atime_ns, st.st_mtime_ns),
|
||||||
|
# [PermissionError] [Errno 1] Operation not permitted, '/windows/_videos'
|
||||||
|
_, _, tb = sys.exc_info()
|
||||||
|
for _, _, fun, _ in traceback.extract_tb(tb):
|
||||||
|
if fun == "copystat":
|
||||||
|
if log:
|
||||||
|
t = "warning: failed to retain some file attributes (timestamp and/or permissions) during copy from %r to %r:\n%s"
|
||||||
|
log(t % (src, dst, min_ex()), 3)
|
||||||
|
return dst # close enough
|
||||||
|
raise
|
||||||
|
|
||||||
|
|
||||||
def _fs_mvrm(
|
def _fs_mvrm(
|
||||||
log: "NamedLogger", src: str, dst: str, atomic: bool, flags: dict[str, Any]
|
log: "NamedLogger", src: str, dst: str, atomic: bool, flags: dict[str, Any]
|
||||||
) -> bool:
|
) -> bool:
|
||||||
|
|
Loading…
Reference in a new issue