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