##// END OF EJS Templates
templater: use a global funcs table
templater: use a global funcs table

File last commit:

r14911:5b395031 default
r14925:ab545a15 default
Show More
posix.py
350 lines | 10.2 KiB | text/x-python | PythonLexer
Martin Geisler
put license and copyright info into comment blocks
r8226 # posix.py - Posix utility function implementations for Mercurial
#
# Copyright 2005-2009 Matt Mackall <mpm@selenic.com> and others
#
# This software may be used and distributed according to the terms of the
Matt Mackall
Update license to GPLv2+
r10263 # GNU General Public License version 2 or any later version.
Matt Mackall
util: split out posix, windows, and win32 modules
r7890
from i18n import _
Adrian Buehlmann
util: move checkexec() to posix.py and return False on Windows
r13879 import os, sys, errno, stat, getpass, pwd, grp, tempfile
Matt Mackall
util: split out posix, windows, and win32 modules
r7890
Alejandro Santos
compat: use open() instead of file() everywhere
r9031 posixfile = open
Matt Mackall
util: split out posix, windows, and win32 modules
r7890 nulldev = '/dev/null'
normpath = os.path.normpath
samestat = os.path.samestat
Adrian Buehlmann
rename util.os_link to oslink
r14235 oslink = os.link
Adrian Buehlmann
reintroduces util.unlink, for POSIX and Windows....
r13280 unlink = os.unlink
Adrian Buehlmann
util: move rename into posix.py and windows.py
r9549 rename = os.rename
Matt Mackall
cmdutils: Take over glob expansion duties from util
r8614 expandglobs = False
Matt Mackall
util: split out posix, windows, and win32 modules
r7890
umask = os.umask(0)
os.umask(umask)
def openhardlinks():
'''return true if it is safe to hold open file handles to hardlinks'''
return True
Adrian Buehlmann
port win32.py to using the Python ctypes library...
r13375 def nlinks(name):
'''return number of hardlinks for the given file'''
return os.lstat(name).st_nlink
Adrian Buehlmann
rename util.parse_patch_output to parsepatchoutput
r14231 def parsepatchoutput(output_line):
timeless
Generally replace "file name" with "filename" in help and comments.
r8761 """parses the output produced by patch and returns the filename"""
Matt Mackall
util: split out posix, windows, and win32 modules
r7890 pf = output_line[14:]
if os.sys.platform == 'OpenVMS':
if pf[0] == '`':
pf = pf[1:-1] # Remove the quotes
else:
Peter Arrenbrecht
whitespace cleanup
r8219 if pf.startswith("'") and pf.endswith("'") and " " in pf:
Matt Mackall
util: split out posix, windows, and win32 modules
r7890 pf = pf[1:-1] # Remove the quotes
return pf
def sshargs(sshcmd, host, user, port):
'''Build argument list for ssh'''
args = user and ("%s@%s" % (user, host)) or host
return port and ("%s -p %s" % (args, port)) or args
Adrian Buehlmann
rename util.is_exec to isexec
r14273 def isexec(f):
Matt Mackall
util: split out posix, windows, and win32 modules
r7890 """check whether a file is executable"""
return (os.lstat(f).st_mode & 0100 != 0)
Adrian Buehlmann
rename util.set_flags to setflags
r14232 def setflags(f, l, x):
Matt Mackall
util: split out posix, windows, and win32 modules
r7890 s = os.lstat(f).st_mode
if l:
if not stat.S_ISLNK(s):
# switch file to link
Dan Villiom Podlaski Christiansen
explicitly close files...
r13400 fp = open(f)
data = fp.read()
fp.close()
Matt Mackall
util: split out posix, windows, and win32 modules
r7890 os.unlink(f)
try:
os.symlink(data, f)
Idan Kamara
eliminate various naked except clauses
r14004 except OSError:
Matt Mackall
util: split out posix, windows, and win32 modules
r7890 # failed to make a link, rewrite file
Dan Villiom Podlaski Christiansen
explicitly close files...
r13400 fp = open(f, "w")
fp.write(data)
fp.close()
Matt Mackall
util: split out posix, windows, and win32 modules
r7890 # no chmod needed at this point
return
if stat.S_ISLNK(s):
# switch link to file
data = os.readlink(f)
os.unlink(f)
Dan Villiom Podlaski Christiansen
explicitly close files...
r13400 fp = open(f, "w")
fp.write(data)
fp.close()
Matt Mackall
util: split out posix, windows, and win32 modules
r7890 s = 0666 & ~umask # avoid restatting for chmod
sx = s & 0100
if x and not sx:
# Turn on +x for every +r bit when making a file executable
# and obey umask.
os.chmod(f, s | (s & 0444) >> 2 & ~umask)
elif not x and sx:
# Turn off all +x bits
os.chmod(f, s & 0666)
Adrian Buehlmann
util: move checkexec() to posix.py and return False on Windows
r13879 def checkexec(path):
"""
Check whether the given path is on a filesystem with UNIX-like exec flags
Requires a directory (like /foo/.hg)
"""
# VFAT on some Linux versions can flip mode but it doesn't persist
# a FS remount. Frequently we can detect it if files are created
# with exec bit on.
try:
EXECFLAGS = stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH
fh, fn = tempfile.mkstemp(dir=path, prefix='hg-checkexec-')
try:
os.close(fh)
m = os.stat(fn).st_mode & 0777
new_file_has_exec = m & EXECFLAGS
os.chmod(fn, m ^ EXECFLAGS)
exec_flags_cannot_flip = ((os.stat(fn).st_mode & 0777) == m)
finally:
os.unlink(fn)
except (IOError, OSError):
# we don't care, the user probably won't be able to commit anyway
return False
return not (new_file_has_exec or exec_flags_cannot_flip)
Adrian Buehlmann
util: move checklink() to posix.py and return False on Windows...
r13890 def checklink(path):
"""check whether the given path is on a symlink-capable filesystem"""
# mktemp is not racy because symlink creation will fail if the
# file already exists
name = tempfile.mktemp(dir=path, prefix='hg-checklink-')
try:
os.symlink(".", name)
os.unlink(name)
return True
except (OSError, AttributeError):
return False
Adrian Buehlmann
path_auditor: check filenames for basic platform validity (issue2755)...
r13916 def checkosfilename(path):
'''Check that the base-relative path is a valid filename on this platform.
Returns None if the path is ok, or a UI string describing the problem.'''
pass # on posix platforms, every path is ok
Adrian Buehlmann
rename util.set_binary to setbinary
r14233 def setbinary(fd):
Matt Mackall
util: split out posix, windows, and win32 modules
r7890 pass
def pconvert(path):
return path
def localpath(path):
return path
Siddharth Agarwal
Add support for relinking on Windows....
r10218 def samefile(fpath1, fpath2):
"""Returns whether path1 and path2 refer to the same file. This is only
guaranteed to work for files, not directories."""
return os.path.samefile(fpath1, fpath2)
def samedevice(fpath1, fpath2):
"""Returns whether fpath1 and fpath2 are on the same device. This is only
guaranteed to work for files, not directories."""
st1 = os.lstat(fpath1)
st2 = os.lstat(fpath2)
return st1.st_dev == st2.st_dev
Dan Villiom Podlaski Christiansen
util: add realpath() for getting the 'true' path....
r9238 if sys.platform == 'darwin':
Ronny Pfannschmidt
posix: move a global fcntl import to keep it from breaking jython...
r10757 import fcntl # only needed on darwin, missing on jython
Dan Villiom Podlaski Christiansen
util: add realpath() for getting the 'true' path....
r9238 def realpath(path):
'''
Returns the true, canonical file system path equivalent to the given
path.
Equivalent means, in this case, resulting in the same, unique
file system link to the path. Every file system entry, whether a file,
directory, hard link or symbolic link or special, will have a single
path preferred by the system, but may allow multiple, differing path
lookups to point to it.
Most regular UNIX file systems only allow a file system entry to be
looked up by its distinct path. Obviously, this does not apply to case
insensitive file systems, whether case preserving or not. The most
complex issue to deal with is file systems transparently reencoding the
path, such as the non-standard Unicode normalisation required for HFS+
and HFSX.
'''
# Constants copied from /usr/include/sys/fcntl.h
F_GETPATH = 50
O_SYMLINK = 0x200000
try:
fd = os.open(path, O_SYMLINK)
except OSError, err:
Dan Villiom Podlaski Christiansen
posix: remove is-comparison between integers...
r13007 if err.errno == errno.ENOENT:
Dan Villiom Podlaski Christiansen
util: add realpath() for getting the 'true' path....
r9238 return path
raise
try:
return fcntl.fcntl(fd, F_GETPATH, '\0' * 1024).rstrip('\0')
finally:
os.close(fd)
else:
# Fallback to the likely inadequate Python builtin function.
realpath = os.path.realpath
Matt Mackall
util: split out posix, windows, and win32 modules
r7890 def shellquote(s):
if os.sys.platform == 'OpenVMS':
return '"%s"' % s
else:
return "'%s'" % s.replace("'", "'\\''")
def quotecommand(cmd):
return cmd
def popen(command, mode='r'):
return os.popen(command, mode)
def testpid(pid):
'''return False if pid dead, True if running or not sure'''
if os.sys.platform == 'OpenVMS':
return True
try:
os.kill(pid, 0)
return True
except OSError, inst:
return inst.errno != errno.ESRCH
Adrian Buehlmann
rename explain_exit to explainexit
r14234 def explainexit(code):
Mads Kiilerich
util.system: Use subprocess instead of os.system...
r9517 """return a 2-tuple (desc, code) describing a subprocess status
(codes from kill are negative - not os.system/wait encoding)"""
if code >= 0:
return _("exited with status %d") % code, code
return _("killed by signal %d") % -code, -code
Matt Mackall
util: split out posix, windows, and win32 modules
r7890
Martin Geisler
posix: do not use fstat in isowner...
r8657 def isowner(st):
"""Return True if the stat object st is from the current user."""
Matt Mackall
util: split out posix, windows, and win32 modules
r7890 return st.st_uid == os.getuid()
Adrian Buehlmann
rename util.find_exe to findexe
r14271 def findexe(command):
Matt Mackall
util: split out posix, windows, and win32 modules
r7890 '''Find executable for command searching like which does.
If command is a basename then PATH is searched for command.
PATH isn't searched if command is an absolute or relative path.
If command isn't found None is returned.'''
if sys.platform == 'OpenVMS':
return command
def findexisting(executable):
'Will return executable if existing file'
if os.path.exists(executable):
return executable
return None
if os.sep in command:
return findexisting(command)
for path in os.environ.get('PATH', '').split(os.pathsep):
executable = findexisting(os.path.join(path, command))
if executable is not None:
return executable
return None
Adrian Buehlmann
rename util.set_signal_handler to setsignalhandler
r14237 def setsignalhandler():
Matt Mackall
util: split out posix, windows, and win32 modules
r7890 pass
def statfiles(files):
'Stat each file in files and yield stat or None if file does not exist.'
lstat = os.lstat
for nf in files:
try:
st = lstat(nf)
except OSError, err:
if err.errno not in (errno.ENOENT, errno.ENOTDIR):
raise
st = None
yield st
def getuser():
'''return name of current user'''
return getpass.getuser()
def username(uid=None):
"""Return the name of the user with the given uid.
If uid is None, return the name of the current user."""
if uid is None:
uid = os.getuid()
try:
return pwd.getpwuid(uid)[0]
except KeyError:
return str(uid)
def groupname(gid=None):
"""Return the name of the group with the given gid.
If gid is None, return the name of the current group."""
if gid is None:
gid = os.getgid()
try:
return grp.getgrgid(gid)[0]
except KeyError:
return str(gid)
Patrick Mezard
serve: add and use portable spawnvp replacement...
r10237
Patrick Mezard
acl: grp module is not available on windows
r11138 def groupmembers(name):
"""Return the list of members of the group with the given
name, KeyError if the group does not exist.
"""
return list(grp.getgrnam(name).gr_mem)
Patrick Mezard
serve: add and use portable spawnvp replacement...
r10237 def spawndetached(args):
return os.spawnvp(os.P_NOWAIT | getattr(os, 'P_DETACH', 0),
args[0], args)
Patrick Mezard
Find right hg command for detached process...
r10239 def gethgcmd():
return sys.argv[:1]
Patrick Mezard
util: fix default termwidth() under Windows...
r11010
Augie Fackler
termwidth: move to ui.ui from util
r12689 def termwidth():
Patrick Mezard
util: fix default termwidth() under Windows...
r11010 try:
import termios, array, fcntl
for dev in (sys.stderr, sys.stdout, sys.stdin):
try:
try:
fd = dev.fileno()
except AttributeError:
continue
if not os.isatty(fd):
continue
arri = fcntl.ioctl(fd, termios.TIOCGWINSZ, '\0' * 8)
jfh
util.termwidth: never return 0 for terminal width...
r14165 width = array.array('h', arri)[1]
if width > 0:
return width
Patrick Mezard
util: fix default termwidth() under Windows...
r11010 except ValueError:
pass
except IOError, e:
if e[0] == errno.EINVAL:
pass
else:
raise
except ImportError:
pass
return 80
Adrian Buehlmann
util: move "default" makedir to posix.py...
r14908
def makedir(path, notindexed):
os.mkdir(path)
Adrian Buehlmann
util: move "default" unlinkpath to posix.py...
r14909
def unlinkpath(f):
"""unlink and remove the directory if it is empty"""
os.unlink(f)
# try removing directories that might now be empty
try:
os.removedirs(os.path.dirname(f))
except OSError:
pass
Adrian Buehlmann
util: move "default" lookupreg to posix.py...
r14910 def lookupreg(key, name=None, scope=None):
return None
Adrian Buehlmann
util: move "default" hidewindow to posix.py...
r14911
def hidewindow():
"""Hide current shell window.
Used to hide the window opened when starting asynchronous
child process under Windows, unneeded on other systems.
"""
pass