From 1e2febdb37fb9cc2ab7c93855a4623a1607de3d0 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 21 Mar 2014 09:20:33 +0530 Subject: [PATCH] Linux build: Workaround for systems that have broken libc implementations that change the behavior of truncate() on file descriptors with O_APPEND set. Fixes #1295366 [json config files get corrupted when using Python 2.7.6 on Linux](https://bugs.launchpad.net/calibre/+bug/1295366) --- src/calibre/utils/lock.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/calibre/utils/lock.py b/src/calibre/utils/lock.py index b2156d48c8..5090c11cf8 100644 --- a/src/calibre/utils/lock.py +++ b/src/calibre/utils/lock.py @@ -8,7 +8,7 @@ Secure access to locked files from multiple processes. from calibre.constants import iswindows, __appname__, \ win32api, win32event, winerror, fcntl -import time, atexit, os +import time, atexit, os, stat class LockError(Exception): pass @@ -105,6 +105,12 @@ class WindowsExclFile(object): def closed(self): return self._handle is None +def unix_open(path): + # We cannot use open(a+b) directly because Fedora apparently ships with a + # broken libc that causes seek(0) followed by truncate() to not work for + # files with O_APPEND set. + fd = os.open(path, os.O_RDWR | os.O_CREAT, stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH) + return os.fdopen(fd, 'r+b') class ExclusiveFile(object): @@ -113,7 +119,7 @@ class ExclusiveFile(object): self.timeout = timeout def __enter__(self): - self.file = WindowsExclFile(self.path, self.timeout) if iswindows else open(self.path, 'a+b') + self.file = WindowsExclFile(self.path, self.timeout) if iswindows else unix_open(self.path) self.file.seek(0) timeout = self.timeout if not iswindows: