From 1ebaca2486fe5bbc23f372bf2cba580e85aaf844 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 7 Feb 2016 08:55:15 +0530 Subject: [PATCH] Fix file handles to files on the device being inherited by idling worker processes, preventing the device from being ejected --- src/calibre/devices/usbms/cli.py | 8 ++++---- src/calibre/devices/usbms/driver.py | 10 +++++----- src/calibre/utils/filenames.py | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/calibre/devices/usbms/cli.py b/src/calibre/devices/usbms/cli.py index 6482a5b12b..83cfc0dd91 100644 --- a/src/calibre/devices/usbms/cli.py +++ b/src/calibre/devices/usbms/cli.py @@ -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) @@ -60,7 +60,7 @@ class CLI(object): dest.truncate() shutil.copyfileobj(infile, dest) fsync(dest) - #if not check_transfer(infile, dest): raise Exception('Transfer failed') + # if not check_transfer(infile, dest): raise Exception('Transfer failed') if close: infile.close() return actual_path @@ -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) diff --git a/src/calibre/devices/usbms/driver.py b/src/calibre/devices/usbms/driver.py index 9e53022488..bb07f46651 100644 --- a/src/calibre/devices/usbms/driver.py +++ b/src/calibre/devices/usbms/driver.py @@ -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 diff --git a/src/calibre/utils/filenames.py b/src/calibre/utils/filenames.py index 9a0d77e5d0..913c0836e1 100644 --- a/src/calibre/utils/filenames.py +++ b/src/calibre/utils/filenames.py @@ -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.