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