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. We also use O_CLOEXEC when it is available, # to ensure there are no races. flags = os.O_RDWR | os.O_CREAT from calibre.constants import plugins speedup = plugins['speedup'][0] has_cloexec = False if hasattr(speedup, 'O_CLOEXEC'): try: fd = os.open( path, flags | speedup.O_CLOEXEC, stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH ) has_cloexec = True except EnvironmentError as err: if getattr(err, 'errno', None) == errno.EINVAL: # Kernel does not support O_CLOEXEC fd = os.open( path, flags, stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH ) else: raise else: fd = os.open( path, flags, stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH ) if not has_cloexec: fcntl.fcntl(fd, fcntl.F_SETFD, fcntl.FD_CLOEXEC) return os.fdopen(fd, 'r+b')
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. We also use O_CLOEXEC when it is available, # to ensure there are no races. flags = os.O_RDWR | os.O_CREAT from calibre.constants import plugins speedup = plugins['speedup'][0] has_cloexec = False if hasattr(speedup, 'O_CLOEXEC'): try: fd = os.open( path, flags | speedup.O_CLOEXEC, stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH) has_cloexec = True except EnvironmentError as err: if getattr( err, 'errno', None) == errno.EINVAL: # Kernel does not support O_CLOEXEC fd = os.open( path, flags, stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH) else: raise else: fd = os.open(path, flags, stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH) if not has_cloexec: fcntl.fcntl(fd, fcntl.F_SETFD, fcntl.FD_CLOEXEC) return os.fdopen(fd, 'r+b')
def unix_open(path): flags = os.O_RDWR | os.O_CREAT has_cloexec = False if hasattr(speedup, 'O_CLOEXEC'): try: fd = os.open(path, flags | speedup.O_CLOEXEC, excl_file_mode) has_cloexec = True except EnvironmentError as err: # Kernel may not support O_CLOEXEC if err.errno != errno.EINVAL: raise if not has_cloexec: fd = os.open(path, flags, excl_file_mode) fcntl.fcntl(fd, fcntl.F_SETFD, fcntl.FD_CLOEXEC) return os.fdopen(fd, 'r+b')
def singleinstance(name): import socket from calibre.utils.ipc import eintr_retry_call name = '%s-singleinstance-%s-%d' % (__appname__, name, os.geteuid()) if not isinstance(name, bytes): name = name.encode('utf-8') address = b'\0' + name.replace(b' ', b'_') sock = socket.socket(family=socket.AF_UNIX) try: eintr_retry_call(sock.bind, address) except socket.error as err: if getattr(err, 'errno', None) == errno.EADDRINUSE: return False raise fd = sock.fileno() old_flags = fcntl.fcntl(fd, fcntl.F_GETFD) fcntl.fcntl(fd, fcntl.F_SETFD, old_flags | fcntl.FD_CLOEXEC) atexit.register(sock.close) return True
def create_single_instance_mutex(name, per_user=True): import socket from calibre.utils.ipc import eintr_retry_call name = '%s-singleinstance-%s-%s' % (__appname__, (os.geteuid() if per_user else ''), name) name = name.encode('utf-8') address = b'\0' + name.replace(b' ', b'_') sock = socket.socket(family=socket.AF_UNIX) try: eintr_retry_call(sock.bind, address) except socket.error as err: if getattr(err, 'errno', None) == errno.EADDRINUSE: return raise fd = sock.fileno() old_flags = fcntl.fcntl(fd, fcntl.F_GETFD) fcntl.fcntl(fd, fcntl.F_SETFD, old_flags | fcntl.FD_CLOEXEC) return sock.close
def create_single_instance_mutex(name, per_user=True): import socket from calibre.utils.ipc import eintr_retry_call name = '%s-singleinstance-%s-%s' % ( __appname__, (os.geteuid() if per_user else ''), name ) name = name.encode('utf-8') address = b'\0' + name.replace(b' ', b'_') sock = socket.socket(family=socket.AF_UNIX) try: eintr_retry_call(sock.bind, address) except socket.error as err: if getattr(err, 'errno', None) == errno.EADDRINUSE: return raise fd = sock.fileno() old_flags = fcntl.fcntl(fd, fcntl.F_GETFD) fcntl.fcntl(fd, fcntl.F_SETFD, old_flags | fcntl.FD_CLOEXEC) return sock.close
def singleinstance(name): ''' Return True if no other instance of the application identified by name is running, False otherwise. @param name: The name to lock. @type name: string ''' from calibre.utils.ipc import eintr_retry_call path = singleinstance_path(name) f = open(path, 'w') old_flags = fcntl.fcntl(f.fileno(), fcntl.F_GETFD) fcntl.fcntl(f.fileno(), fcntl.F_SETFD, old_flags | fcntl.FD_CLOEXEC) try: eintr_retry_call(fcntl.lockf, f.fileno(), fcntl.LOCK_EX|fcntl.LOCK_NB) atexit.register(_clean_lock_file, f) return True except IOError as err: if err.errno == errno.EAGAIN: return False raise return False
def singleinstance(name): ''' Return True if no other instance of the application identified by name is running, False otherwise. @param name: The name to lock. @type name: string ''' from calibre.utils.ipc import eintr_retry_call path = singleinstance_path(name) f = open(path, 'w') old_flags = fcntl.fcntl(f.fileno(), fcntl.F_GETFD) fcntl.fcntl(f.fileno(), fcntl.F_SETFD, old_flags | fcntl.FD_CLOEXEC) try: eintr_retry_call(fcntl.lockf, f.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB) atexit.register(_clean_lock_file, f) return True except IOError as err: if err.errno == errno.EAGAIN: return False raise return False
def test_exclusive_file_same_process(self): fname = 'testsp' with ExclusiveFile(fname): ef = FastFailEF(fname) self.assertRaises(EnvironmentError, ef.__enter__) t = Other() t.start(), t.join() self.assertIs(t.locked, False) if not iswindows: with unix_open(fname) as f: self.assertEqual( 1, fcntl.fcntl(f.fileno(), fcntl.F_GETFD) & fcntl.FD_CLOEXEC)
def test_exclusive_file_same_process(self): fname = 'testsp' with ExclusiveFile(fname): ef = FastFailEF(fname) self.assertRaises(EnvironmentError, ef.__enter__) t = Other() t.start(), t.join() self.assertIs(t.locked, False) if not iswindows: with unix_open(fname) as f: self.assertEqual( 1, fcntl.fcntl(f.fileno(), fcntl.F_GETFD) & fcntl.FD_CLOEXEC )