Lock file f using lockf and dot locking.
(f, dotlock=True)
| 2062 | |
| 2063 | |
| 2064 | def _lock_file(f, dotlock=True): |
| 2065 | """Lock file f using lockf and dot locking.""" |
| 2066 | dotlock_done = False |
| 2067 | try: |
| 2068 | if fcntl: |
| 2069 | try: |
| 2070 | fcntl.lockf(f, fcntl.LOCK_EX | fcntl.LOCK_NB) |
| 2071 | except OSError as e: |
| 2072 | if e.errno in (errno.EAGAIN, errno.EACCES, errno.EROFS): |
| 2073 | raise ExternalClashError('lockf: lock unavailable: %s' % |
| 2074 | f.name) |
| 2075 | else: |
| 2076 | raise |
| 2077 | if dotlock: |
| 2078 | try: |
| 2079 | pre_lock = _create_temporary(f.name + '.lock') |
| 2080 | pre_lock.close() |
| 2081 | except OSError as e: |
| 2082 | if e.errno in (errno.EACCES, errno.EROFS): |
| 2083 | return # Without write access, just skip dotlocking. |
| 2084 | else: |
| 2085 | raise |
| 2086 | try: |
| 2087 | try: |
| 2088 | os.link(pre_lock.name, f.name + '.lock') |
| 2089 | dotlock_done = True |
| 2090 | except (AttributeError, PermissionError): |
| 2091 | os.rename(pre_lock.name, f.name + '.lock') |
| 2092 | dotlock_done = True |
| 2093 | else: |
| 2094 | os.unlink(pre_lock.name) |
| 2095 | except FileExistsError: |
| 2096 | os.remove(pre_lock.name) |
| 2097 | raise ExternalClashError('dot lock unavailable: %s' % |
| 2098 | f.name) |
| 2099 | except: |
| 2100 | if fcntl: |
| 2101 | fcntl.lockf(f, fcntl.LOCK_UN) |
| 2102 | if dotlock_done: |
| 2103 | os.remove(f.name + '.lock') |
| 2104 | raise |
| 2105 | |
| 2106 | def _unlock_file(f): |
| 2107 | """Unlock file f using lockf and dot locking.""" |
no test coverage detected