Fix file handles to files on the device being inherited by idling worker processes, preventing the device from being ejected

This commit is contained in:
Kovid Goyal 2016-02-07 08:55:15 +05:30
parent b4c6c5a316
commit 1ebaca2486
3 changed files with 10 additions and 10 deletions

View File

@ -35,14 +35,14 @@ class CLI(object):
def get_file(self, path, outfile, end_session=True):
path = self.munge_path(path)
with open(path, 'rb') as src:
with lopen(path, 'rb') as src:
shutil.copyfileobj(src, outfile)
def put_file(self, infile, path, replace_file=False, end_session=True):
path = self.munge_path(path)
close = False
if not hasattr(infile, 'read'):
infile, close = open(infile, 'rb'), True
infile, close = lopen(infile, 'rb'), True
infile.seek(0)
if os.path.isdir(path):
path = os.path.join(path, infile.name)
@ -100,6 +100,6 @@ class CLI(object):
def touch(self, path, end_session=True):
path = self.munge_path(path)
if not os.path.exists(path):
open(path, 'w').close()
lopen(path, 'w').close()
if not os.path.isdir(path):
os.utime(path, None)

View File

@ -117,19 +117,19 @@ class USBMS(CLI, Device):
def _update_driveinfo_file(self, prefix, location_code, name=None):
from calibre.utils.config import from_json, to_json
if os.path.exists(os.path.join(prefix, self.DRIVEINFO)):
with open(os.path.join(prefix, self.DRIVEINFO), 'rb') as f:
with lopen(os.path.join(prefix, self.DRIVEINFO), 'rb') as f:
try:
driveinfo = json.loads(f.read(), object_hook=from_json)
except:
driveinfo = None
driveinfo = self._update_driveinfo_record(driveinfo, prefix,
location_code, name)
with open(os.path.join(prefix, self.DRIVEINFO), 'wb') as f:
with lopen(os.path.join(prefix, self.DRIVEINFO), 'wb') as f:
f.write(json.dumps(driveinfo, default=to_json))
fsync(f)
else:
driveinfo = self._update_driveinfo_record({}, prefix, location_code, name)
with open(os.path.join(prefix, self.DRIVEINFO), 'wb') as f:
with lopen(os.path.join(prefix, self.DRIVEINFO), 'wb') as f:
f.write(json.dumps(driveinfo, default=to_json))
fsync(f)
return driveinfo
@ -439,7 +439,7 @@ class USBMS(CLI, Device):
isinstance(booklists[listid], self.booklist_class)):
if not os.path.exists(prefix):
os.makedirs(self.normalize_path(prefix))
with open(self.normalize_path(os.path.join(prefix, self.METADATA_CACHE)), 'wb') as f:
with lopen(self.normalize_path(os.path.join(prefix, self.METADATA_CACHE)), 'wb') as f:
json_codec.encode_to_file(f, booklists[listid])
fsync(f)
write_prefix(self._main_prefix, 0)
@ -485,7 +485,7 @@ class USBMS(CLI, Device):
cache_file = cls.normalize_path(os.path.join(prefix, name))
if os.access(cache_file, os.R_OK):
try:
with open(cache_file, 'rb') as f:
with lopen(cache_file, 'rb') as f:
json_codec.decode_from_file(f, bl, cls.book_class, prefix)
except:
import traceback

View File

@ -181,7 +181,7 @@ def case_preserving_open_file(path, mode='wb', mkdir_mode=0o777):
ans = fpath = cpath
else:
fname = components[-1]
ans = open(os.path.join(cpath, fname), mode)
ans = lopen(os.path.join(cpath, fname), mode)
# Ensure file and all its metadata is written to disk so that subsequent
# listdir() has file name in it. I don't know if this is actually
# necessary, but given the diversity of platforms, best to be safe.