mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
On windows add a wait when hardlinking to account for broken network
filesystems
This commit is contained in:
parent
f5eda364e6
commit
3b345d3ff5
@ -3,7 +3,7 @@ Make strings safe for use as ASCII filenames, while trying to preserve as much
|
||||
meaning as possible.
|
||||
'''
|
||||
|
||||
import os, errno
|
||||
import os, errno, time
|
||||
from math import ceil
|
||||
|
||||
from calibre import sanitize_file_name, isbytestring, force_unicode
|
||||
@ -257,6 +257,19 @@ def samefile(src, dst):
|
||||
os.path.normcase(os.path.abspath(dst)))
|
||||
return samestring
|
||||
|
||||
def windows_get_size(path):
|
||||
''' On windows file sizes are only accurately stored in the actual file,
|
||||
not in the directory entry (which could be out of date). So we open the
|
||||
file, and get the actual size. '''
|
||||
import win32file
|
||||
h = win32file.CreateFile(
|
||||
path, 0, win32file.FILE_SHARE_READ | win32file.FILE_SHARE_WRITE | win32file.FILE_SHARE_DELETE,
|
||||
None, win32file.OPEN_EXISTING, 0, None)
|
||||
try:
|
||||
return win32file.GetFileSize(h)
|
||||
finally:
|
||||
win32file.CloseHandle(h)
|
||||
|
||||
def windows_hardlink(src, dest):
|
||||
import win32file, pywintypes
|
||||
try:
|
||||
@ -264,17 +277,21 @@ def windows_hardlink(src, dest):
|
||||
except pywintypes.error as e:
|
||||
msg = u'Creating hardlink from %s to %s failed: %%s' % (src, dest)
|
||||
raise Exception(msg % e)
|
||||
src_size = os.path.getsize(src)
|
||||
# We open and close dest, to ensure its directory entry is updated
|
||||
# see http://blogs.msdn.com/b/oldnewthing/archive/2011/12/26/10251026.aspx
|
||||
h = win32file.CreateFile(
|
||||
dest, 0, win32file.FILE_SHARE_READ | win32file.FILE_SHARE_WRITE | win32file.FILE_SHARE_DELETE,
|
||||
None, win32file.OPEN_EXISTING, 0, None)
|
||||
try:
|
||||
sz = win32file.GetFileSize(h)
|
||||
finally:
|
||||
win32file.CloseHandle(h)
|
||||
for i in range(10):
|
||||
# If we are on a network filesystem, we have to wait for some indeterminate time, since
|
||||
# network file systems are the best thing since sliced bread
|
||||
try:
|
||||
if windows_get_size(dest) == src_size:
|
||||
return
|
||||
except EnvironmentError:
|
||||
pass
|
||||
time.sleep(0.3)
|
||||
|
||||
if sz != os.path.getsize(src):
|
||||
sz = windows_get_size(dest)
|
||||
if sz != src_size:
|
||||
msg = u'Creating hardlink from %s to %s failed: %%s' % (src, dest)
|
||||
raise Exception(msg % ('hardlink size: %d not the same as source size' % sz))
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user