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