|
5 | 5 | # the BSD License: http://www.opensource.org/licenses/bsd-license.php
|
6 | 6 | from __future__ import unicode_literals
|
7 | 7 |
|
8 |
| -from fcntl import flock, LOCK_UN, LOCK_EX, LOCK_NB |
9 | 8 | import getpass
|
10 | 9 | import logging
|
11 | 10 | import os
|
|
49 | 48 |
|
50 | 49 | #{ Utility Methods
|
51 | 50 |
|
| 51 | +if platform.system() == 'Windows': |
| 52 | + # This code is a derivative work of Portalocker http://code.activestate.com/recipes/65203/ |
| 53 | + import win32con |
| 54 | + import win32file |
| 55 | + import pywintypes |
| 56 | + |
| 57 | + LOCK_EX = win32con.LOCKFILE_EXCLUSIVE_LOCK |
| 58 | + LOCK_SH = 0 # the default |
| 59 | + LOCK_NB = win32con.LOCKFILE_FAIL_IMMEDIATELY |
| 60 | + LOCK_UN = 1 << 2 |
| 61 | + |
| 62 | + __overlapped = pywintypes.OVERLAPPED() |
| 63 | + |
| 64 | + def flock(fd, flags=0): |
| 65 | + hfile = win32file._get_osfhandle(fd) |
| 66 | + |
| 67 | + if flags & LOCK_UN != 0: |
| 68 | + # Unlock file descriptor |
| 69 | + try: |
| 70 | + win32file.UnlockFileEx(hfile, 0, -0x10000, __overlapped) |
| 71 | + except pywintypes.error, exc_value: |
| 72 | + # error: (158, 'UnlockFileEx', 'The segment is already unlocked.') |
| 73 | + # To match the 'posix' implementation, silently ignore this error |
| 74 | + if exc_value[0] == 158: |
| 75 | + pass |
| 76 | + else: |
| 77 | + # Q: Are there exceptions/codes we should be dealing with here? |
| 78 | + raise |
| 79 | + |
| 80 | + elif flags & LOCK_EX != 0: |
| 81 | + # Lock file |
| 82 | + try: |
| 83 | + win32file.LockFileEx(hfile, flags, 0, -0x10000, __overlapped) |
| 84 | + except pywintypes.error, exc_value: |
| 85 | + if exc_value[0] == 33: |
| 86 | + # error: (33, 'LockFileEx', |
| 87 | + # 'The process cannot access the file because another process has locked |
| 88 | + # a portion of the file.') |
| 89 | + raise IOError(33, exc_value[2]) |
| 90 | + else: |
| 91 | + # Q: Are there exceptions/codes we should be dealing with here? |
| 92 | + raise |
| 93 | + |
| 94 | + else: |
| 95 | + raise NotImplementedError("Unsupported set of bitflags {}".format(bin(flags))) |
| 96 | + |
| 97 | + |
| 98 | +else: |
| 99 | + # from fcntl import flock, LOCK_UN, LOCK_EX, LOCK_NB |
| 100 | + pass |
| 101 | + |
52 | 102 |
|
53 | 103 | def unbare_repo(func):
|
54 | 104 | """Methods with this decorator raise InvalidGitRepositoryError if they
|
@@ -620,6 +670,7 @@ def _release_lock(self):
|
620 | 670 | rmfile(lock_file)
|
621 | 671 | except OSError:
|
622 | 672 | pass
|
| 673 | + |
623 | 674 | self._owns_lock = False
|
624 | 675 | self._file_descriptor = None
|
625 | 676 |
|
|
0 commit comments