Fix #1513849 [Edit E-Book will not save after editing if original file is not in its directory.](https://bugs.launchpad.net/calibre/+bug/1513849)

This commit is contained in:
Kovid Goyal 2015-11-06 20:25:24 +05:30
parent 2f8c415f49
commit 66c4618556

View File

@ -34,6 +34,7 @@ def save_container(container, path):
if hasattr(os, 'fchmod'): if hasattr(os, 'fchmod'):
# Ensure file permissions and owner information is preserved # Ensure file permissions and owner information is preserved
fno = temp.fileno() fno = temp.fileno()
st = None
try: try:
st = os.stat(path) st = os.stat(path)
except EnvironmentError as err: except EnvironmentError as err:
@ -41,22 +42,28 @@ def save_container(container, path):
raise raise
# path may not exist if we are saving a copy, in which case we use # path may not exist if we are saving a copy, in which case we use
# the metadata from the original book # the metadata from the original book
st = os.stat(container.path_to_ebook) try:
try: st = os.stat(container.path_to_ebook)
os.fchmod(fno, st.st_mode) except EnvironmentError as err:
except EnvironmentError as err: if err.errno != errno.ENOENT:
if err.errno != errno.EPERM: raise
raise # Somebody deleted the original file
raise EnvironmentError('Failed to change permissions of %s to %s (%s), with error: %s. Most likely the %s directory has a restrictive umask' % ( if st is not None:
temp.name, oct(st.st_mode), format_permissions(st.st_mode), errno.errorcode[err.errno], os.path.dirname(temp.name))) try:
try: os.fchmod(fno, st.st_mode)
os.fchown(fno, st.st_uid, st.st_gid) except EnvironmentError as err:
except EnvironmentError as err: if err.errno != errno.EPERM:
if err.errno not in (errno.EPERM, errno.EACCES): raise
# ignore chown failure as user could be editing file belonging raise EnvironmentError('Failed to change permissions of %s to %s (%s), with error: %s. Most likely the %s directory has a restrictive umask' % (
# to a different user, in which case we really cant do anything temp.name, oct(st.st_mode), format_permissions(st.st_mode), errno.errorcode[err.errno], os.path.dirname(temp.name)))
# about it short of making the file update non-atomic try:
raise os.fchown(fno, st.st_uid, st.st_gid)
except EnvironmentError as err:
if err.errno not in (errno.EPERM, errno.EACCES):
# ignore chown failure as user could be editing file belonging
# to a different user, in which case we really cant do anything
# about it short of making the file update non-atomic
raise
temp.close() temp.close()
temp = temp.name temp = temp.name