##// END OF EJS Templates
posix: move a global fcntl import to keep it from breaking jython...
Ronny Pfannschmidt -
r10757:ab378245 default
parent child Browse files
Show More
@@ -1,266 +1,267
1 1 # posix.py - Posix utility function implementations for Mercurial
2 2 #
3 3 # Copyright 2005-2009 Matt Mackall <mpm@selenic.com> and others
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 from i18n import _
9 9 import osutil
10 import os, sys, errno, stat, getpass, pwd, grp, fcntl
10 import os, sys, errno, stat, getpass, pwd, grp
11 11
12 12 posixfile = open
13 13 nulldev = '/dev/null'
14 14 normpath = os.path.normpath
15 15 samestat = os.path.samestat
16 16 rename = os.rename
17 17 expandglobs = False
18 18
19 19 umask = os.umask(0)
20 20 os.umask(umask)
21 21
22 22 def openhardlinks():
23 23 '''return true if it is safe to hold open file handles to hardlinks'''
24 24 return True
25 25
26 26 def rcfiles(path):
27 27 rcs = [os.path.join(path, 'hgrc')]
28 28 rcdir = os.path.join(path, 'hgrc.d')
29 29 try:
30 30 rcs.extend([os.path.join(rcdir, f)
31 31 for f, kind in osutil.listdir(rcdir)
32 32 if f.endswith(".rc")])
33 33 except OSError:
34 34 pass
35 35 return rcs
36 36
37 37 def system_rcpath():
38 38 path = []
39 39 # old mod_python does not set sys.argv
40 40 if len(getattr(sys, 'argv', [])) > 0:
41 41 path.extend(rcfiles(os.path.dirname(sys.argv[0]) +
42 42 '/../etc/mercurial'))
43 43 path.extend(rcfiles('/etc/mercurial'))
44 44 return path
45 45
46 46 def user_rcpath():
47 47 return [os.path.expanduser('~/.hgrc')]
48 48
49 49 def parse_patch_output(output_line):
50 50 """parses the output produced by patch and returns the filename"""
51 51 pf = output_line[14:]
52 52 if os.sys.platform == 'OpenVMS':
53 53 if pf[0] == '`':
54 54 pf = pf[1:-1] # Remove the quotes
55 55 else:
56 56 if pf.startswith("'") and pf.endswith("'") and " " in pf:
57 57 pf = pf[1:-1] # Remove the quotes
58 58 return pf
59 59
60 60 def sshargs(sshcmd, host, user, port):
61 61 '''Build argument list for ssh'''
62 62 args = user and ("%s@%s" % (user, host)) or host
63 63 return port and ("%s -p %s" % (args, port)) or args
64 64
65 65 def is_exec(f):
66 66 """check whether a file is executable"""
67 67 return (os.lstat(f).st_mode & 0100 != 0)
68 68
69 69 def set_flags(f, l, x):
70 70 s = os.lstat(f).st_mode
71 71 if l:
72 72 if not stat.S_ISLNK(s):
73 73 # switch file to link
74 74 data = open(f).read()
75 75 os.unlink(f)
76 76 try:
77 77 os.symlink(data, f)
78 78 except:
79 79 # failed to make a link, rewrite file
80 80 open(f, "w").write(data)
81 81 # no chmod needed at this point
82 82 return
83 83 if stat.S_ISLNK(s):
84 84 # switch link to file
85 85 data = os.readlink(f)
86 86 os.unlink(f)
87 87 open(f, "w").write(data)
88 88 s = 0666 & ~umask # avoid restatting for chmod
89 89
90 90 sx = s & 0100
91 91 if x and not sx:
92 92 # Turn on +x for every +r bit when making a file executable
93 93 # and obey umask.
94 94 os.chmod(f, s | (s & 0444) >> 2 & ~umask)
95 95 elif not x and sx:
96 96 # Turn off all +x bits
97 97 os.chmod(f, s & 0666)
98 98
99 99 def set_binary(fd):
100 100 pass
101 101
102 102 def pconvert(path):
103 103 return path
104 104
105 105 def localpath(path):
106 106 return path
107 107
108 108 def samefile(fpath1, fpath2):
109 109 """Returns whether path1 and path2 refer to the same file. This is only
110 110 guaranteed to work for files, not directories."""
111 111 return os.path.samefile(fpath1, fpath2)
112 112
113 113 def samedevice(fpath1, fpath2):
114 114 """Returns whether fpath1 and fpath2 are on the same device. This is only
115 115 guaranteed to work for files, not directories."""
116 116 st1 = os.lstat(fpath1)
117 117 st2 = os.lstat(fpath2)
118 118 return st1.st_dev == st2.st_dev
119 119
120 120 if sys.platform == 'darwin':
121 import fcntl # only needed on darwin, missing on jython
121 122 def realpath(path):
122 123 '''
123 124 Returns the true, canonical file system path equivalent to the given
124 125 path.
125 126
126 127 Equivalent means, in this case, resulting in the same, unique
127 128 file system link to the path. Every file system entry, whether a file,
128 129 directory, hard link or symbolic link or special, will have a single
129 130 path preferred by the system, but may allow multiple, differing path
130 131 lookups to point to it.
131 132
132 133 Most regular UNIX file systems only allow a file system entry to be
133 134 looked up by its distinct path. Obviously, this does not apply to case
134 135 insensitive file systems, whether case preserving or not. The most
135 136 complex issue to deal with is file systems transparently reencoding the
136 137 path, such as the non-standard Unicode normalisation required for HFS+
137 138 and HFSX.
138 139 '''
139 140 # Constants copied from /usr/include/sys/fcntl.h
140 141 F_GETPATH = 50
141 142 O_SYMLINK = 0x200000
142 143
143 144 try:
144 145 fd = os.open(path, O_SYMLINK)
145 146 except OSError, err:
146 147 if err.errno is errno.ENOENT:
147 148 return path
148 149 raise
149 150
150 151 try:
151 152 return fcntl.fcntl(fd, F_GETPATH, '\0' * 1024).rstrip('\0')
152 153 finally:
153 154 os.close(fd)
154 155 else:
155 156 # Fallback to the likely inadequate Python builtin function.
156 157 realpath = os.path.realpath
157 158
158 159 def shellquote(s):
159 160 if os.sys.platform == 'OpenVMS':
160 161 return '"%s"' % s
161 162 else:
162 163 return "'%s'" % s.replace("'", "'\\''")
163 164
164 165 def quotecommand(cmd):
165 166 return cmd
166 167
167 168 def popen(command, mode='r'):
168 169 return os.popen(command, mode)
169 170
170 171 def testpid(pid):
171 172 '''return False if pid dead, True if running or not sure'''
172 173 if os.sys.platform == 'OpenVMS':
173 174 return True
174 175 try:
175 176 os.kill(pid, 0)
176 177 return True
177 178 except OSError, inst:
178 179 return inst.errno != errno.ESRCH
179 180
180 181 def explain_exit(code):
181 182 """return a 2-tuple (desc, code) describing a subprocess status
182 183 (codes from kill are negative - not os.system/wait encoding)"""
183 184 if code >= 0:
184 185 return _("exited with status %d") % code, code
185 186 return _("killed by signal %d") % -code, -code
186 187
187 188 def isowner(st):
188 189 """Return True if the stat object st is from the current user."""
189 190 return st.st_uid == os.getuid()
190 191
191 192 def find_exe(command):
192 193 '''Find executable for command searching like which does.
193 194 If command is a basename then PATH is searched for command.
194 195 PATH isn't searched if command is an absolute or relative path.
195 196 If command isn't found None is returned.'''
196 197 if sys.platform == 'OpenVMS':
197 198 return command
198 199
199 200 def findexisting(executable):
200 201 'Will return executable if existing file'
201 202 if os.path.exists(executable):
202 203 return executable
203 204 return None
204 205
205 206 if os.sep in command:
206 207 return findexisting(command)
207 208
208 209 for path in os.environ.get('PATH', '').split(os.pathsep):
209 210 executable = findexisting(os.path.join(path, command))
210 211 if executable is not None:
211 212 return executable
212 213 return None
213 214
214 215 def set_signal_handler():
215 216 pass
216 217
217 218 def statfiles(files):
218 219 'Stat each file in files and yield stat or None if file does not exist.'
219 220 lstat = os.lstat
220 221 for nf in files:
221 222 try:
222 223 st = lstat(nf)
223 224 except OSError, err:
224 225 if err.errno not in (errno.ENOENT, errno.ENOTDIR):
225 226 raise
226 227 st = None
227 228 yield st
228 229
229 230 def getuser():
230 231 '''return name of current user'''
231 232 return getpass.getuser()
232 233
233 234 def expand_glob(pats):
234 235 '''On Windows, expand the implicit globs in a list of patterns'''
235 236 return list(pats)
236 237
237 238 def username(uid=None):
238 239 """Return the name of the user with the given uid.
239 240
240 241 If uid is None, return the name of the current user."""
241 242
242 243 if uid is None:
243 244 uid = os.getuid()
244 245 try:
245 246 return pwd.getpwuid(uid)[0]
246 247 except KeyError:
247 248 return str(uid)
248 249
249 250 def groupname(gid=None):
250 251 """Return the name of the group with the given gid.
251 252
252 253 If gid is None, return the name of the current group."""
253 254
254 255 if gid is None:
255 256 gid = os.getgid()
256 257 try:
257 258 return grp.getgrgid(gid)[0]
258 259 except KeyError:
259 260 return str(gid)
260 261
261 262 def spawndetached(args):
262 263 return os.spawnvp(os.P_NOWAIT | getattr(os, 'P_DETACH', 0),
263 264 args[0], args)
264 265
265 266 def gethgcmd():
266 267 return sys.argv[:1]
General Comments 0
You need to be logged in to leave comments. Login now