##// END OF EJS Templates
Make makelock and readlock work on filesystems without symlink support....
Thomas Arendsen Hein -
r704:5ca319a6 default
parent child Browse files
Show More
@@ -1,49 +1,49 b''
1 1 # lock.py - simple locking scheme for mercurial
2 2 #
3 3 # Copyright 2005 Matt Mackall <mpm@selenic.com>
4 4 #
5 5 # This software may be used and distributed according to the terms
6 6 # of the GNU General Public License, incorporated herein by reference.
7 7
8 8 import os, time
9 9 import util
10 10
11 11 class LockHeld(Exception):
12 12 pass
13 13
14 14 class lock:
15 15 def __init__(self, file, wait = 1):
16 16 self.f = file
17 17 self.held = 0
18 18 self.wait = wait
19 19 self.lock()
20 20
21 21 def __del__(self):
22 22 self.release()
23 23
24 24 def lock(self):
25 25 while 1:
26 26 try:
27 27 self.trylock()
28 28 return 1
29 29 except LockHeld, inst:
30 30 if self.wait:
31 31 time.sleep(1)
32 32 continue
33 33 raise inst
34 34
35 35 def trylock(self):
36 36 pid = os.getpid()
37 37 try:
38 38 util.makelock(str(pid), self.f)
39 39 self.held = 1
40 except:
40 except (OSError, IOError):
41 41 raise LockHeld(util.readlock(self.f))
42 42
43 43 def release(self):
44 44 if self.held:
45 45 self.held = 0
46 46 try:
47 47 os.unlink(self.f)
48 48 except: pass
49 49
@@ -1,111 +1,126 b''
1 1 # util.py - utility functions and platform specfic implementations
2 2 #
3 3 # Copyright 2005 K. Thananchayan <thananck@yahoo.com>
4 4 #
5 5 # This software may be used and distributed according to the terms
6 6 # of the GNU General Public License, incorporated herein by reference.
7 7
8 import os
8 import os, errno
9 9
10 10 def unique(g):
11 11 seen = {}
12 12 for f in g:
13 13 if f not in seen:
14 14 seen[f] = 1
15 15 yield f
16 16
17 17 class CommandError(Exception): pass
18 18
19 19 def explain_exit(code):
20 20 """return a 2-tuple (desc, code) describing a process's status"""
21 21 if os.WIFEXITED(code):
22 22 val = os.WEXITSTATUS(code)
23 23 return "exited with status %d" % val, val
24 24 elif os.WIFSIGNALED(code):
25 25 val = os.WTERMSIG(code)
26 26 return "killed by signal %d" % val, val
27 27 elif os.WIFSTOPPED(code):
28 28 val = os.WSTOPSIG(code)
29 29 return "stopped by signal %d" % val, val
30 30 raise ValueError("invalid exit code")
31 31
32 32 def system(cmd, errprefix=None):
33 33 """execute a shell command that must succeed"""
34 34 rc = os.system(cmd)
35 35 if rc:
36 36 errmsg = "%s %s" % (os.path.basename(cmd.split(None, 1)[0]),
37 37 explain_exit(rc)[0])
38 38 if errprefix:
39 39 errmsg = "%s: %s" % (errprefix, errmsg)
40 40 raise CommandError(errmsg)
41 41
42 42 def rename(src, dst):
43 43 try:
44 44 os.rename(src, dst)
45 45 except:
46 46 os.unlink(dst)
47 47 os.rename(src, dst)
48 48
49 49 def copytree(src, dst, copyfile):
50 50 """Copy a directory tree, files are copied using 'copyfile'."""
51 51 names = os.listdir(src)
52 52 os.mkdir(dst)
53 53
54 54 for name in names:
55 55 srcname = os.path.join(src, name)
56 56 dstname = os.path.join(dst, name)
57 57 if os.path.isdir(srcname):
58 58 copytree(srcname, dstname, copyfile)
59 59 elif os.path.isfile(srcname):
60 60 copyfile(srcname, dstname)
61 61 else:
62 62 raise IOError("Not a regular file: %r" % srcname)
63 63
64 def _makelock_file(info, pathname):
65 ld = os.open(pathname, os.O_CREAT | os.O_WRONLY | os.O_EXCL)
66 os.write(ld, info)
67 os.close(ld)
68
69 def _readlock_file(pathname):
70 return file(pathname).read()
71
64 72 # Platfor specific varients
65 73 if os.name == 'nt':
66 74 nulldev = 'NUL:'
67 75
68 76 def is_exec(f, last):
69 77 return last
70 78
71 79 def set_exec(f, mode):
72 80 pass
73 81
74 82 def pconvert(path):
75 83 return path.replace("\\", "/")
76 84
77 def makelock(info, pathname):
78 ld = os.open(pathname, os.O_CREAT | os.O_WRONLY | os.O_EXCL)
79 os.write(ld, info)
80 os.close(ld)
81
82 def readlock(pathname):
83 return file(pathname).read()
85 makelock = _makelock_file
86 readlock = _readlock_file
84 87
85 88 else:
86 89 nulldev = '/dev/null'
87 90
88 91 def is_exec(f, last):
89 92 return (os.stat(f).st_mode & 0100 != 0)
90 93
91 94 def set_exec(f, mode):
92 95 s = os.stat(f).st_mode
93 96 if (s & 0100 != 0) == mode:
94 97 return
95 98 if mode:
96 99 # Turn on +x for every +r bit when making a file executable
97 100 # and obey umask.
98 101 umask = os.umask(0)
99 102 os.umask(umask)
100 103 os.chmod(f, s | (s & 0444) >> 2 & ~umask)
101 104 else:
102 105 os.chmod(f, s & 0666)
103 106
104 107 def pconvert(path):
105 108 return path
106 109
107 110 def makelock(info, pathname):
108 os.symlink(info, pathname)
111 try:
112 os.symlink(info, pathname)
113 except OSError, why:
114 if why.errno == errno.EEXIST:
115 raise
116 else:
117 _makelock_file(info, pathname)
109 118
110 119 def readlock(pathname):
111 return os.readlink(pathname)
120 try:
121 return os.readlink(pathname)
122 except OSError, why:
123 if why.errno == errno.EINVAL:
124 return _readlock_file(pathname)
125 else:
126 raise
General Comments 0
You need to be logged in to leave comments. Login now