Lock file f using lockf and dot locking.
(f, dotlock=True)
| 2133 | |
| 2134 | |
| 2135 | def _lock_file(f, dotlock=True): |
| 2136 | """Lock file f using lockf and dot locking.""" |
| 2137 | dotlock_done = False |
| 2138 | try: |
| 2139 | if fcntl: |
| 2140 | try: |
| 2141 | fcntl.lockf(f, fcntl.LOCK_EX | fcntl.LOCK_NB) |
| 2142 | except OSError as e: |
| 2143 | if e.errno in (errno.EAGAIN, errno.EACCES, errno.EROFS): |
| 2144 | raise ExternalClashError('lockf: lock unavailable: %s' % |
| 2145 | f.name) |
| 2146 | else: |
| 2147 | raise |
| 2148 | if dotlock: |
| 2149 | try: |
| 2150 | pre_lock = _create_temporary(f.name + '.lock') |
| 2151 | pre_lock.close() |
| 2152 | except OSError as e: |
| 2153 | if e.errno in (errno.EACCES, errno.EROFS): |
| 2154 | return # Without write access, just skip dotlocking. |
| 2155 | else: |
| 2156 | raise |
| 2157 | try: |
| 2158 | try: |
| 2159 | os.link(pre_lock.name, f.name + '.lock') |
| 2160 | dotlock_done = True |
| 2161 | except (AttributeError, PermissionError): |
| 2162 | os.rename(pre_lock.name, f.name + '.lock') |
| 2163 | dotlock_done = True |
| 2164 | else: |
| 2165 | os.unlink(pre_lock.name) |
| 2166 | except FileExistsError: |
| 2167 | os.remove(pre_lock.name) |
| 2168 | raise ExternalClashError('dot lock unavailable: %s' % |
| 2169 | f.name) |
| 2170 | except: |
| 2171 | if fcntl: |
| 2172 | fcntl.lockf(f, fcntl.LOCK_UN) |
| 2173 | if dotlock_done: |
| 2174 | os.remove(f.name + '.lock') |
| 2175 | raise |
| 2176 | |
| 2177 | def _unlock_file(f): |
| 2178 | """Unlock file f using lockf and dot locking.""" |
no test coverage detected