mercurial/posix.py
author FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
Tue, 01 Oct 2013 00:35:07 +0900
branchstable
changeset 19849 e7fa36d2ad3a
parent 19514 cfdae231ba78
child 20202 a6014018ec28
permissions -rw-r--r--
rebase: catch RepoLookupError at restoring rebase state for summary Before this patch, "hg summary" may fail, when there is inconsistent rebase state: for example, the root of rebase destination revisions recorded in rebase state file is already stripped manually. Mercurial earlier than 2.7 allows users to do anything other than starting new rebase, even though current rebase is not finished or aborted yet. So, such inconsistent rebase states may be left and forgotten in repositories. This patch catches RepoLookupError at restoring rebase state for summary hook, and treat such state as "broken".
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
8226
8b2cd04a6e97 put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents: 8225
diff changeset
     1
# posix.py - Posix utility function implementations for Mercurial
8b2cd04a6e97 put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents: 8225
diff changeset
     2
#
8b2cd04a6e97 put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents: 8225
diff changeset
     3
#  Copyright 2005-2009 Matt Mackall <mpm@selenic.com> and others
8b2cd04a6e97 put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents: 8225
diff changeset
     4
#
8b2cd04a6e97 put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents: 8225
diff changeset
     5
# This software may be used and distributed according to the terms of the
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 10218
diff changeset
     6
# GNU General Public License version 2 or any later version.
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     7
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     8
from i18n import _
17203
0cb55b5c19a3 util, posix: eliminate encodinglower and encodingupper
Adrian Buehlmann <adrian@cadifra.com>
parents: 16726
diff changeset
     9
import encoding
18097
ae54cff742e2 posix: move server side of unix domain sockets out of inotify
Bryan O'Sullivan <bryano@fb.com>
parents: 18017
diff changeset
    10
import os, sys, errno, stat, getpass, pwd, grp, socket, tempfile, unicodedata
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    11
9031
3b76321aa0de compat: use open() instead of file() everywhere
Alejandro Santos <alejolp@alejolp.com>
parents: 8761
diff changeset
    12
posixfile = open
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    13
normpath = os.path.normpath
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    14
samestat = os.path.samestat
14235
b9e1b041744f rename util.os_link to oslink
Adrian Buehlmann <adrian@cadifra.com>
parents: 14234
diff changeset
    15
oslink = os.link
13280
6052bbc7aabd reintroduces util.unlink, for POSIX and Windows.
Adrian Buehlmann <adrian@cadifra.com>
parents: 13007
diff changeset
    16
unlink = os.unlink
9549
8b8920209317 util: move rename into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 9517
diff changeset
    17
rename = os.rename
8614
573734e7e6d0 cmdutils: Take over glob expansion duties from util
Matt Mackall <mpm@selenic.com>
parents: 8312
diff changeset
    18
expandglobs = False
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    19
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    20
umask = os.umask(0)
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    21
os.umask(umask)
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    22
17560
9ee25d7b1aed util: implement a faster os.path.split for posix systems
Bryan O'Sullivan <bryano@fb.com>
parents: 17391
diff changeset
    23
def split(p):
18288
0d5a22f73a1f posix: fix split() for the case where the path is at the root of the filesystem
Remy Blank <remy.blank@pobox.com>
parents: 18143
diff changeset
    24
    '''Same as posixpath.split, but faster
0d5a22f73a1f posix: fix split() for the case where the path is at the root of the filesystem
Remy Blank <remy.blank@pobox.com>
parents: 18143
diff changeset
    25
0d5a22f73a1f posix: fix split() for the case where the path is at the root of the filesystem
Remy Blank <remy.blank@pobox.com>
parents: 18143
diff changeset
    26
    >>> import posixpath
0d5a22f73a1f posix: fix split() for the case where the path is at the root of the filesystem
Remy Blank <remy.blank@pobox.com>
parents: 18143
diff changeset
    27
    >>> for f in ['/absolute/path/to/file',
0d5a22f73a1f posix: fix split() for the case where the path is at the root of the filesystem
Remy Blank <remy.blank@pobox.com>
parents: 18143
diff changeset
    28
    ...           'relative/path/to/file',
0d5a22f73a1f posix: fix split() for the case where the path is at the root of the filesystem
Remy Blank <remy.blank@pobox.com>
parents: 18143
diff changeset
    29
    ...           'file_alone',
0d5a22f73a1f posix: fix split() for the case where the path is at the root of the filesystem
Remy Blank <remy.blank@pobox.com>
parents: 18143
diff changeset
    30
    ...           'path/to/directory/',
0d5a22f73a1f posix: fix split() for the case where the path is at the root of the filesystem
Remy Blank <remy.blank@pobox.com>
parents: 18143
diff changeset
    31
    ...           '/multiple/path//separators',
0d5a22f73a1f posix: fix split() for the case where the path is at the root of the filesystem
Remy Blank <remy.blank@pobox.com>
parents: 18143
diff changeset
    32
    ...           '/file_at_root',
0d5a22f73a1f posix: fix split() for the case where the path is at the root of the filesystem
Remy Blank <remy.blank@pobox.com>
parents: 18143
diff changeset
    33
    ...           '///multiple_leading_separators_at_root',
0d5a22f73a1f posix: fix split() for the case where the path is at the root of the filesystem
Remy Blank <remy.blank@pobox.com>
parents: 18143
diff changeset
    34
    ...           '']:
0d5a22f73a1f posix: fix split() for the case where the path is at the root of the filesystem
Remy Blank <remy.blank@pobox.com>
parents: 18143
diff changeset
    35
    ...     assert split(f) == posixpath.split(f), f
0d5a22f73a1f posix: fix split() for the case where the path is at the root of the filesystem
Remy Blank <remy.blank@pobox.com>
parents: 18143
diff changeset
    36
    '''
17560
9ee25d7b1aed util: implement a faster os.path.split for posix systems
Bryan O'Sullivan <bryano@fb.com>
parents: 17391
diff changeset
    37
    ht = p.rsplit('/', 1)
9ee25d7b1aed util: implement a faster os.path.split for posix systems
Bryan O'Sullivan <bryano@fb.com>
parents: 17391
diff changeset
    38
    if len(ht) == 1:
9ee25d7b1aed util: implement a faster os.path.split for posix systems
Bryan O'Sullivan <bryano@fb.com>
parents: 17391
diff changeset
    39
        return '', p
9ee25d7b1aed util: implement a faster os.path.split for posix systems
Bryan O'Sullivan <bryano@fb.com>
parents: 17391
diff changeset
    40
    nh = ht[0].rstrip('/')
9ee25d7b1aed util: implement a faster os.path.split for posix systems
Bryan O'Sullivan <bryano@fb.com>
parents: 17391
diff changeset
    41
    if nh:
9ee25d7b1aed util: implement a faster os.path.split for posix systems
Bryan O'Sullivan <bryano@fb.com>
parents: 17391
diff changeset
    42
        return nh, ht[1]
18288
0d5a22f73a1f posix: fix split() for the case where the path is at the root of the filesystem
Remy Blank <remy.blank@pobox.com>
parents: 18143
diff changeset
    43
    return ht[0] + '/', ht[1]
17560
9ee25d7b1aed util: implement a faster os.path.split for posix systems
Bryan O'Sullivan <bryano@fb.com>
parents: 17391
diff changeset
    44
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    45
def openhardlinks():
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    46
    '''return true if it is safe to hold open file handles to hardlinks'''
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    47
    return True
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    48
13375
f1fa8f481c7c port win32.py to using the Python ctypes library
Adrian Buehlmann <adrian@cadifra.com>
parents: 13280
diff changeset
    49
def nlinks(name):
f1fa8f481c7c port win32.py to using the Python ctypes library
Adrian Buehlmann <adrian@cadifra.com>
parents: 13280
diff changeset
    50
    '''return number of hardlinks for the given file'''
f1fa8f481c7c port win32.py to using the Python ctypes library
Adrian Buehlmann <adrian@cadifra.com>
parents: 13280
diff changeset
    51
    return os.lstat(name).st_nlink
f1fa8f481c7c port win32.py to using the Python ctypes library
Adrian Buehlmann <adrian@cadifra.com>
parents: 13280
diff changeset
    52
14231
8abe4db2d162 rename util.parse_patch_output to parsepatchoutput
Adrian Buehlmann <adrian@cadifra.com>
parents: 14165
diff changeset
    53
def parsepatchoutput(output_line):
8761
0289f384e1e5 Generally replace "file name" with "filename" in help and comments.
timeless <timeless@gmail.com>
parents: 8657
diff changeset
    54
    """parses the output produced by patch and returns the filename"""
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    55
    pf = output_line[14:]
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    56
    if os.sys.platform == 'OpenVMS':
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    57
        if pf[0] == '`':
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    58
            pf = pf[1:-1] # Remove the quotes
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    59
    else:
8219
21cf74ff2deb whitespace cleanup
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7943
diff changeset
    60
        if pf.startswith("'") and pf.endswith("'") and " " in pf:
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    61
            pf = pf[1:-1] # Remove the quotes
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    62
    return pf
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    63
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    64
def sshargs(sshcmd, host, user, port):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    65
    '''Build argument list for ssh'''
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    66
    args = user and ("%s@%s" % (user, host)) or host
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    67
    return port and ("%s -p %s" % (args, port)) or args
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    68
14273
38af0f514134 rename util.is_exec to isexec
Adrian Buehlmann <adrian@cadifra.com>
parents: 14272
diff changeset
    69
def isexec(f):
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    70
    """check whether a file is executable"""
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    71
    return (os.lstat(f).st_mode & 0100 != 0)
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    72
14232
df2399663392 rename util.set_flags to setflags
Adrian Buehlmann <adrian@cadifra.com>
parents: 14231
diff changeset
    73
def setflags(f, l, x):
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    74
    s = os.lstat(f).st_mode
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    75
    if l:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    76
        if not stat.S_ISLNK(s):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    77
            # switch file to link
13400
14f3795a5ed7 explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 13375
diff changeset
    78
            fp = open(f)
14f3795a5ed7 explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 13375
diff changeset
    79
            data = fp.read()
14f3795a5ed7 explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 13375
diff changeset
    80
            fp.close()
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    81
            os.unlink(f)
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    82
            try:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    83
                os.symlink(data, f)
14004
97ed99d1f419 eliminate various naked except clauses
Idan Kamara <idankk86@gmail.com>
parents: 13986
diff changeset
    84
            except OSError:
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    85
                # failed to make a link, rewrite file
13400
14f3795a5ed7 explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 13375
diff changeset
    86
                fp = open(f, "w")
14f3795a5ed7 explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 13375
diff changeset
    87
                fp.write(data)
14f3795a5ed7 explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 13375
diff changeset
    88
                fp.close()
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    89
        # no chmod needed at this point
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    90
        return
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    91
    if stat.S_ISLNK(s):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    92
        # switch link to file
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    93
        data = os.readlink(f)
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    94
        os.unlink(f)
13400
14f3795a5ed7 explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 13375
diff changeset
    95
        fp = open(f, "w")
14f3795a5ed7 explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 13375
diff changeset
    96
        fp.write(data)
14f3795a5ed7 explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 13375
diff changeset
    97
        fp.close()
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    98
        s = 0666 & ~umask # avoid restatting for chmod
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    99
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   100
    sx = s & 0100
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   101
    if x and not sx:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   102
        # Turn on +x for every +r bit when making a file executable
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   103
        # and obey umask.
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   104
        os.chmod(f, s | (s & 0444) >> 2 & ~umask)
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   105
    elif not x and sx:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   106
        # Turn off all +x bits
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   107
        os.chmod(f, s & 0666)
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   108
15011
5e44e4b3a0a3 util: move copymode into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 14927
diff changeset
   109
def copymode(src, dst, mode=None):
5e44e4b3a0a3 util: move copymode into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 14927
diff changeset
   110
    '''Copy the file mode from the file at path src to dst.
5e44e4b3a0a3 util: move copymode into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 14927
diff changeset
   111
    If src doesn't exist, we're using mode instead. If mode is None, we're
5e44e4b3a0a3 util: move copymode into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 14927
diff changeset
   112
    using umask.'''
5e44e4b3a0a3 util: move copymode into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 14927
diff changeset
   113
    try:
5e44e4b3a0a3 util: move copymode into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 14927
diff changeset
   114
        st_mode = os.lstat(src).st_mode & 0777
5e44e4b3a0a3 util: move copymode into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 14927
diff changeset
   115
    except OSError, inst:
5e44e4b3a0a3 util: move copymode into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 14927
diff changeset
   116
        if inst.errno != errno.ENOENT:
5e44e4b3a0a3 util: move copymode into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 14927
diff changeset
   117
            raise
5e44e4b3a0a3 util: move copymode into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 14927
diff changeset
   118
        st_mode = mode
5e44e4b3a0a3 util: move copymode into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 14927
diff changeset
   119
        if st_mode is None:
5e44e4b3a0a3 util: move copymode into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 14927
diff changeset
   120
            st_mode = ~umask
5e44e4b3a0a3 util: move copymode into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 14927
diff changeset
   121
        st_mode &= 0666
5e44e4b3a0a3 util: move copymode into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 14927
diff changeset
   122
    os.chmod(dst, st_mode)
5e44e4b3a0a3 util: move copymode into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 14927
diff changeset
   123
13879
5b0a3f6cbead util: move checkexec() to posix.py and return False on Windows
Adrian Buehlmann <adrian@cadifra.com>
parents: 13400
diff changeset
   124
def checkexec(path):
5b0a3f6cbead util: move checkexec() to posix.py and return False on Windows
Adrian Buehlmann <adrian@cadifra.com>
parents: 13400
diff changeset
   125
    """
5b0a3f6cbead util: move checkexec() to posix.py and return False on Windows
Adrian Buehlmann <adrian@cadifra.com>
parents: 13400
diff changeset
   126
    Check whether the given path is on a filesystem with UNIX-like exec flags
5b0a3f6cbead util: move checkexec() to posix.py and return False on Windows
Adrian Buehlmann <adrian@cadifra.com>
parents: 13400
diff changeset
   127
5b0a3f6cbead util: move checkexec() to posix.py and return False on Windows
Adrian Buehlmann <adrian@cadifra.com>
parents: 13400
diff changeset
   128
    Requires a directory (like /foo/.hg)
5b0a3f6cbead util: move checkexec() to posix.py and return False on Windows
Adrian Buehlmann <adrian@cadifra.com>
parents: 13400
diff changeset
   129
    """
5b0a3f6cbead util: move checkexec() to posix.py and return False on Windows
Adrian Buehlmann <adrian@cadifra.com>
parents: 13400
diff changeset
   130
5b0a3f6cbead util: move checkexec() to posix.py and return False on Windows
Adrian Buehlmann <adrian@cadifra.com>
parents: 13400
diff changeset
   131
    # VFAT on some Linux versions can flip mode but it doesn't persist
5b0a3f6cbead util: move checkexec() to posix.py and return False on Windows
Adrian Buehlmann <adrian@cadifra.com>
parents: 13400
diff changeset
   132
    # a FS remount. Frequently we can detect it if files are created
5b0a3f6cbead util: move checkexec() to posix.py and return False on Windows
Adrian Buehlmann <adrian@cadifra.com>
parents: 13400
diff changeset
   133
    # with exec bit on.
5b0a3f6cbead util: move checkexec() to posix.py and return False on Windows
Adrian Buehlmann <adrian@cadifra.com>
parents: 13400
diff changeset
   134
5b0a3f6cbead util: move checkexec() to posix.py and return False on Windows
Adrian Buehlmann <adrian@cadifra.com>
parents: 13400
diff changeset
   135
    try:
5b0a3f6cbead util: move checkexec() to posix.py and return False on Windows
Adrian Buehlmann <adrian@cadifra.com>
parents: 13400
diff changeset
   136
        EXECFLAGS = stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH
5b0a3f6cbead util: move checkexec() to posix.py and return False on Windows
Adrian Buehlmann <adrian@cadifra.com>
parents: 13400
diff changeset
   137
        fh, fn = tempfile.mkstemp(dir=path, prefix='hg-checkexec-')
5b0a3f6cbead util: move checkexec() to posix.py and return False on Windows
Adrian Buehlmann <adrian@cadifra.com>
parents: 13400
diff changeset
   138
        try:
5b0a3f6cbead util: move checkexec() to posix.py and return False on Windows
Adrian Buehlmann <adrian@cadifra.com>
parents: 13400
diff changeset
   139
            os.close(fh)
5b0a3f6cbead util: move checkexec() to posix.py and return False on Windows
Adrian Buehlmann <adrian@cadifra.com>
parents: 13400
diff changeset
   140
            m = os.stat(fn).st_mode & 0777
5b0a3f6cbead util: move checkexec() to posix.py and return False on Windows
Adrian Buehlmann <adrian@cadifra.com>
parents: 13400
diff changeset
   141
            new_file_has_exec = m & EXECFLAGS
5b0a3f6cbead util: move checkexec() to posix.py and return False on Windows
Adrian Buehlmann <adrian@cadifra.com>
parents: 13400
diff changeset
   142
            os.chmod(fn, m ^ EXECFLAGS)
5b0a3f6cbead util: move checkexec() to posix.py and return False on Windows
Adrian Buehlmann <adrian@cadifra.com>
parents: 13400
diff changeset
   143
            exec_flags_cannot_flip = ((os.stat(fn).st_mode & 0777) == m)
5b0a3f6cbead util: move checkexec() to posix.py and return False on Windows
Adrian Buehlmann <adrian@cadifra.com>
parents: 13400
diff changeset
   144
        finally:
5b0a3f6cbead util: move checkexec() to posix.py and return False on Windows
Adrian Buehlmann <adrian@cadifra.com>
parents: 13400
diff changeset
   145
            os.unlink(fn)
5b0a3f6cbead util: move checkexec() to posix.py and return False on Windows
Adrian Buehlmann <adrian@cadifra.com>
parents: 13400
diff changeset
   146
    except (IOError, OSError):
5b0a3f6cbead util: move checkexec() to posix.py and return False on Windows
Adrian Buehlmann <adrian@cadifra.com>
parents: 13400
diff changeset
   147
        # we don't care, the user probably won't be able to commit anyway
5b0a3f6cbead util: move checkexec() to posix.py and return False on Windows
Adrian Buehlmann <adrian@cadifra.com>
parents: 13400
diff changeset
   148
        return False
5b0a3f6cbead util: move checkexec() to posix.py and return False on Windows
Adrian Buehlmann <adrian@cadifra.com>
parents: 13400
diff changeset
   149
    return not (new_file_has_exec or exec_flags_cannot_flip)
5b0a3f6cbead util: move checkexec() to posix.py and return False on Windows
Adrian Buehlmann <adrian@cadifra.com>
parents: 13400
diff changeset
   150
13890
31eb145b50b6 util: move checklink() to posix.py and return False on Windows
Adrian Buehlmann <adrian@cadifra.com>
parents: 13879
diff changeset
   151
def checklink(path):
31eb145b50b6 util: move checklink() to posix.py and return False on Windows
Adrian Buehlmann <adrian@cadifra.com>
parents: 13879
diff changeset
   152
    """check whether the given path is on a symlink-capable filesystem"""
31eb145b50b6 util: move checklink() to posix.py and return False on Windows
Adrian Buehlmann <adrian@cadifra.com>
parents: 13879
diff changeset
   153
    # mktemp is not racy because symlink creation will fail if the
31eb145b50b6 util: move checklink() to posix.py and return False on Windows
Adrian Buehlmann <adrian@cadifra.com>
parents: 13879
diff changeset
   154
    # file already exists
31eb145b50b6 util: move checklink() to posix.py and return False on Windows
Adrian Buehlmann <adrian@cadifra.com>
parents: 13879
diff changeset
   155
    name = tempfile.mktemp(dir=path, prefix='hg-checklink-')
31eb145b50b6 util: move checklink() to posix.py and return False on Windows
Adrian Buehlmann <adrian@cadifra.com>
parents: 13879
diff changeset
   156
    try:
19514
cfdae231ba78 checklink: work around sshfs brain-damage (issue3636)
Matt Mackall <mpm@selenic.com>
parents: 19131
diff changeset
   157
        fd = tempfile.NamedTemporaryFile(dir=path, prefix='hg-checklink-')
cfdae231ba78 checklink: work around sshfs brain-damage (issue3636)
Matt Mackall <mpm@selenic.com>
parents: 19131
diff changeset
   158
        os.symlink(os.path.basename(fd.name), name)
13890
31eb145b50b6 util: move checklink() to posix.py and return False on Windows
Adrian Buehlmann <adrian@cadifra.com>
parents: 13879
diff changeset
   159
        os.unlink(name)
31eb145b50b6 util: move checklink() to posix.py and return False on Windows
Adrian Buehlmann <adrian@cadifra.com>
parents: 13879
diff changeset
   160
        return True
19514
cfdae231ba78 checklink: work around sshfs brain-damage (issue3636)
Matt Mackall <mpm@selenic.com>
parents: 19131
diff changeset
   161
    except AttributeError:
cfdae231ba78 checklink: work around sshfs brain-damage (issue3636)
Matt Mackall <mpm@selenic.com>
parents: 19131
diff changeset
   162
        return False
cfdae231ba78 checklink: work around sshfs brain-damage (issue3636)
Matt Mackall <mpm@selenic.com>
parents: 19131
diff changeset
   163
    except OSError, inst:
cfdae231ba78 checklink: work around sshfs brain-damage (issue3636)
Matt Mackall <mpm@selenic.com>
parents: 19131
diff changeset
   164
        # sshfs might report failure while successfully creating the link
cfdae231ba78 checklink: work around sshfs brain-damage (issue3636)
Matt Mackall <mpm@selenic.com>
parents: 19131
diff changeset
   165
        if inst[0] == errno.EIO and os.path.exists(name):
cfdae231ba78 checklink: work around sshfs brain-damage (issue3636)
Matt Mackall <mpm@selenic.com>
parents: 19131
diff changeset
   166
            os.unlink(name)
13890
31eb145b50b6 util: move checklink() to posix.py and return False on Windows
Adrian Buehlmann <adrian@cadifra.com>
parents: 13879
diff changeset
   167
        return False
31eb145b50b6 util: move checklink() to posix.py and return False on Windows
Adrian Buehlmann <adrian@cadifra.com>
parents: 13879
diff changeset
   168
13916
98ee3dd5bab4 path_auditor: check filenames for basic platform validity (issue2755)
Adrian Buehlmann <adrian@cadifra.com>
parents: 13890
diff changeset
   169
def checkosfilename(path):
98ee3dd5bab4 path_auditor: check filenames for basic platform validity (issue2755)
Adrian Buehlmann <adrian@cadifra.com>
parents: 13890
diff changeset
   170
    '''Check that the base-relative path is a valid filename on this platform.
98ee3dd5bab4 path_auditor: check filenames for basic platform validity (issue2755)
Adrian Buehlmann <adrian@cadifra.com>
parents: 13890
diff changeset
   171
    Returns None if the path is ok, or a UI string describing the problem.'''
98ee3dd5bab4 path_auditor: check filenames for basic platform validity (issue2755)
Adrian Buehlmann <adrian@cadifra.com>
parents: 13890
diff changeset
   172
    pass # on posix platforms, every path is ok
98ee3dd5bab4 path_auditor: check filenames for basic platform validity (issue2755)
Adrian Buehlmann <adrian@cadifra.com>
parents: 13890
diff changeset
   173
14233
659f34b833b9 rename util.set_binary to setbinary
Adrian Buehlmann <adrian@cadifra.com>
parents: 14232
diff changeset
   174
def setbinary(fd):
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   175
    pass
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   176
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   177
def pconvert(path):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   178
    return path
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   179
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   180
def localpath(path):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   181
    return path
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   182
10218
750b7a4f01f6 Add support for relinking on Windows.
Siddharth Agarwal <sid.bugzilla@gmail.com>
parents: 9549
diff changeset
   183
def samefile(fpath1, fpath2):
750b7a4f01f6 Add support for relinking on Windows.
Siddharth Agarwal <sid.bugzilla@gmail.com>
parents: 9549
diff changeset
   184
    """Returns whether path1 and path2 refer to the same file. This is only
750b7a4f01f6 Add support for relinking on Windows.
Siddharth Agarwal <sid.bugzilla@gmail.com>
parents: 9549
diff changeset
   185
    guaranteed to work for files, not directories."""
750b7a4f01f6 Add support for relinking on Windows.
Siddharth Agarwal <sid.bugzilla@gmail.com>
parents: 9549
diff changeset
   186
    return os.path.samefile(fpath1, fpath2)
750b7a4f01f6 Add support for relinking on Windows.
Siddharth Agarwal <sid.bugzilla@gmail.com>
parents: 9549
diff changeset
   187
750b7a4f01f6 Add support for relinking on Windows.
Siddharth Agarwal <sid.bugzilla@gmail.com>
parents: 9549
diff changeset
   188
def samedevice(fpath1, fpath2):
750b7a4f01f6 Add support for relinking on Windows.
Siddharth Agarwal <sid.bugzilla@gmail.com>
parents: 9549
diff changeset
   189
    """Returns whether fpath1 and fpath2 are on the same device. This is only
750b7a4f01f6 Add support for relinking on Windows.
Siddharth Agarwal <sid.bugzilla@gmail.com>
parents: 9549
diff changeset
   190
    guaranteed to work for files, not directories."""
750b7a4f01f6 Add support for relinking on Windows.
Siddharth Agarwal <sid.bugzilla@gmail.com>
parents: 9549
diff changeset
   191
    st1 = os.lstat(fpath1)
750b7a4f01f6 Add support for relinking on Windows.
Siddharth Agarwal <sid.bugzilla@gmail.com>
parents: 9549
diff changeset
   192
    st2 = os.lstat(fpath2)
750b7a4f01f6 Add support for relinking on Windows.
Siddharth Agarwal <sid.bugzilla@gmail.com>
parents: 9549
diff changeset
   193
    return st1.st_dev == st2.st_dev
750b7a4f01f6 Add support for relinking on Windows.
Siddharth Agarwal <sid.bugzilla@gmail.com>
parents: 9549
diff changeset
   194
15488
6eff984d8e76 dirstate: fix case-folding identity for traditional Unix
Matt Mackall <mpm@selenic.com>
parents: 15353
diff changeset
   195
# os.path.normcase is a no-op, which doesn't help us on non-native filesystems
6eff984d8e76 dirstate: fix case-folding identity for traditional Unix
Matt Mackall <mpm@selenic.com>
parents: 15353
diff changeset
   196
def normcase(path):
6eff984d8e76 dirstate: fix case-folding identity for traditional Unix
Matt Mackall <mpm@selenic.com>
parents: 15353
diff changeset
   197
    return path.lower()
6eff984d8e76 dirstate: fix case-folding identity for traditional Unix
Matt Mackall <mpm@selenic.com>
parents: 15353
diff changeset
   198
9238
40196d036a71 util: add realpath() for getting the 'true' path.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 9031
diff changeset
   199
if sys.platform == 'darwin':
10757
ab3782458827 posix: move a global fcntl import to keep it from breaking jython
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 10264
diff changeset
   200
    import fcntl # only needed on darwin, missing on jython
15551
1fa41d1f1351 posix: add extended support for OS X path folding
Matt Mackall <mpm@selenic.com>
parents: 15499
diff changeset
   201
1fa41d1f1351 posix: add extended support for OS X path folding
Matt Mackall <mpm@selenic.com>
parents: 15499
diff changeset
   202
    def normcase(path):
19131
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   203
        '''
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   204
        Normalize a filename for OS X-compatible comparison:
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   205
        - escape-encode invalid characters
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   206
        - decompose to NFD
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   207
        - lowercase
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   208
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   209
        >>> normcase('UPPER')
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   210
        'upper'
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   211
        >>> normcase('Caf\xc3\xa9')
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   212
        'cafe\\xcc\\x81'
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   213
        >>> normcase('\xc3\x89')
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   214
        'e\\xcc\\x81'
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   215
        >>> normcase('\xb8\xca\xc3\xca\xbe\xc8.JPG') # issue3918
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   216
        '%b8%ca%c3\\xca\\xbe%c8.jpg'
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   217
        '''
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   218
15551
1fa41d1f1351 posix: add extended support for OS X path folding
Matt Mackall <mpm@selenic.com>
parents: 15499
diff changeset
   219
        try:
18501
a3b2dc1aa909 OS X: try cheap ascii .lower() in normcase before making full unicode dance
Mads Kiilerich <madski@unity3d.com>
parents: 18442
diff changeset
   220
            path.decode('ascii') # throw exception for non-ASCII character
a3b2dc1aa909 OS X: try cheap ascii .lower() in normcase before making full unicode dance
Mads Kiilerich <madski@unity3d.com>
parents: 18442
diff changeset
   221
            return path.lower()
a3b2dc1aa909 OS X: try cheap ascii .lower() in normcase before making full unicode dance
Mads Kiilerich <madski@unity3d.com>
parents: 18442
diff changeset
   222
        except UnicodeDecodeError:
a3b2dc1aa909 OS X: try cheap ascii .lower() in normcase before making full unicode dance
Mads Kiilerich <madski@unity3d.com>
parents: 18442
diff changeset
   223
            pass
a3b2dc1aa909 OS X: try cheap ascii .lower() in normcase before making full unicode dance
Mads Kiilerich <madski@unity3d.com>
parents: 18442
diff changeset
   224
        try:
15551
1fa41d1f1351 posix: add extended support for OS X path folding
Matt Mackall <mpm@selenic.com>
parents: 15499
diff changeset
   225
            u = path.decode('utf-8')
1fa41d1f1351 posix: add extended support for OS X path folding
Matt Mackall <mpm@selenic.com>
parents: 15499
diff changeset
   226
        except UnicodeDecodeError:
19131
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   227
            # OS X percent-encodes any bytes that aren't valid utf-8
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   228
            s = ''
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   229
            g = ''
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   230
            l = 0
15563
b61fa7481a68 posix: fix HFS+ percent-encoding folding
Matt Mackall <mpm@selenic.com>
parents: 15551
diff changeset
   231
            for c in path:
19131
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   232
                o = ord(c)
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   233
                if l and o < 128 or o >= 192:
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   234
                    # we want a continuation byte, but didn't get one
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   235
                    s += ''.join(["%%%02X" % ord(x) for x in g])
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   236
                    g = ''
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   237
                    l = 0
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   238
                if l == 0 and o < 128:
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   239
                    # ascii
15563
b61fa7481a68 posix: fix HFS+ percent-encoding folding
Matt Mackall <mpm@selenic.com>
parents: 15551
diff changeset
   240
                    s += c
19131
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   241
                elif l == 0 and 194 <= o < 245:
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   242
                    # valid leading bytes
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   243
                    if o < 224:
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   244
                        l = 1
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   245
                    elif o < 240:
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   246
                        l = 2
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   247
                    else:
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   248
                        l = 3
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   249
                    g = c
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   250
                elif l > 0 and 128 <= o < 192:
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   251
                    # valid continuations
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   252
                    g += c
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   253
                    l -= 1
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   254
                    if not l:
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   255
                        s += g
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   256
                        g = ''
15551
1fa41d1f1351 posix: add extended support for OS X path folding
Matt Mackall <mpm@selenic.com>
parents: 15499
diff changeset
   257
                else:
19131
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   258
                    # invalid
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   259
                    s += "%%%02X" % o
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   260
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   261
            # any remaining partial characters
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   262
            s += ''.join(["%%%02X" % ord(x) for x in g])
15551
1fa41d1f1351 posix: add extended support for OS X path folding
Matt Mackall <mpm@selenic.com>
parents: 15499
diff changeset
   263
            u = s.decode('utf-8')
1fa41d1f1351 posix: add extended support for OS X path folding
Matt Mackall <mpm@selenic.com>
parents: 15499
diff changeset
   264
1fa41d1f1351 posix: add extended support for OS X path folding
Matt Mackall <mpm@selenic.com>
parents: 15499
diff changeset
   265
        # Decompose then lowercase (HFS+ technote specifies lower)
1fa41d1f1351 posix: add extended support for OS X path folding
Matt Mackall <mpm@selenic.com>
parents: 15499
diff changeset
   266
        return unicodedata.normalize('NFD', u).lower().encode('utf-8')
1fa41d1f1351 posix: add extended support for OS X path folding
Matt Mackall <mpm@selenic.com>
parents: 15499
diff changeset
   267
9238
40196d036a71 util: add realpath() for getting the 'true' path.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 9031
diff changeset
   268
    def realpath(path):
40196d036a71 util: add realpath() for getting the 'true' path.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 9031
diff changeset
   269
        '''
40196d036a71 util: add realpath() for getting the 'true' path.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 9031
diff changeset
   270
        Returns the true, canonical file system path equivalent to the given
40196d036a71 util: add realpath() for getting the 'true' path.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 9031
diff changeset
   271
        path.
40196d036a71 util: add realpath() for getting the 'true' path.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 9031
diff changeset
   272
40196d036a71 util: add realpath() for getting the 'true' path.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 9031
diff changeset
   273
        Equivalent means, in this case, resulting in the same, unique
40196d036a71 util: add realpath() for getting the 'true' path.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 9031
diff changeset
   274
        file system link to the path. Every file system entry, whether a file,
40196d036a71 util: add realpath() for getting the 'true' path.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 9031
diff changeset
   275
        directory, hard link or symbolic link or special, will have a single
40196d036a71 util: add realpath() for getting the 'true' path.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 9031
diff changeset
   276
        path preferred by the system, but may allow multiple, differing path
40196d036a71 util: add realpath() for getting the 'true' path.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 9031
diff changeset
   277
        lookups to point to it.
40196d036a71 util: add realpath() for getting the 'true' path.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 9031
diff changeset
   278
40196d036a71 util: add realpath() for getting the 'true' path.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 9031
diff changeset
   279
        Most regular UNIX file systems only allow a file system entry to be
40196d036a71 util: add realpath() for getting the 'true' path.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 9031
diff changeset
   280
        looked up by its distinct path. Obviously, this does not apply to case
40196d036a71 util: add realpath() for getting the 'true' path.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 9031
diff changeset
   281
        insensitive file systems, whether case preserving or not. The most
40196d036a71 util: add realpath() for getting the 'true' path.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 9031
diff changeset
   282
        complex issue to deal with is file systems transparently reencoding the
40196d036a71 util: add realpath() for getting the 'true' path.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 9031
diff changeset
   283
        path, such as the non-standard Unicode normalisation required for HFS+
40196d036a71 util: add realpath() for getting the 'true' path.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 9031
diff changeset
   284
        and HFSX.
40196d036a71 util: add realpath() for getting the 'true' path.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 9031
diff changeset
   285
        '''
40196d036a71 util: add realpath() for getting the 'true' path.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 9031
diff changeset
   286
        # Constants copied from /usr/include/sys/fcntl.h
40196d036a71 util: add realpath() for getting the 'true' path.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 9031
diff changeset
   287
        F_GETPATH = 50
40196d036a71 util: add realpath() for getting the 'true' path.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 9031
diff changeset
   288
        O_SYMLINK = 0x200000
40196d036a71 util: add realpath() for getting the 'true' path.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 9031
diff changeset
   289
40196d036a71 util: add realpath() for getting the 'true' path.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 9031
diff changeset
   290
        try:
40196d036a71 util: add realpath() for getting the 'true' path.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 9031
diff changeset
   291
            fd = os.open(path, O_SYMLINK)
40196d036a71 util: add realpath() for getting the 'true' path.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 9031
diff changeset
   292
        except OSError, err:
13007
e98bf6948092 posix: remove is-comparison between integers
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 12689
diff changeset
   293
            if err.errno == errno.ENOENT:
9238
40196d036a71 util: add realpath() for getting the 'true' path.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 9031
diff changeset
   294
                return path
40196d036a71 util: add realpath() for getting the 'true' path.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 9031
diff changeset
   295
            raise
40196d036a71 util: add realpath() for getting the 'true' path.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 9031
diff changeset
   296
40196d036a71 util: add realpath() for getting the 'true' path.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 9031
diff changeset
   297
        try:
40196d036a71 util: add realpath() for getting the 'true' path.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 9031
diff changeset
   298
            return fcntl.fcntl(fd, F_GETPATH, '\0' * 1024).rstrip('\0')
40196d036a71 util: add realpath() for getting the 'true' path.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 9031
diff changeset
   299
        finally:
40196d036a71 util: add realpath() for getting the 'true' path.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 9031
diff changeset
   300
            os.close(fd)
15353
ab600a25dfc0 posix: workaround for os.path.realpath bug in Python 2.4.1 and before
Thomas Arendsen Hein <thomas@intevation.de>
parents: 15056
diff changeset
   301
elif sys.version_info < (2, 4, 2, 'final'):
ab600a25dfc0 posix: workaround for os.path.realpath bug in Python 2.4.1 and before
Thomas Arendsen Hein <thomas@intevation.de>
parents: 15056
diff changeset
   302
    # Workaround for http://bugs.python.org/issue1213894 (os.path.realpath
ab600a25dfc0 posix: workaround for os.path.realpath bug in Python 2.4.1 and before
Thomas Arendsen Hein <thomas@intevation.de>
parents: 15056
diff changeset
   303
    # didn't resolve symlinks that were the first component of the path.)
ab600a25dfc0 posix: workaround for os.path.realpath bug in Python 2.4.1 and before
Thomas Arendsen Hein <thomas@intevation.de>
parents: 15056
diff changeset
   304
    def realpath(path):
ab600a25dfc0 posix: workaround for os.path.realpath bug in Python 2.4.1 and before
Thomas Arendsen Hein <thomas@intevation.de>
parents: 15056
diff changeset
   305
        if os.path.isabs(path):
ab600a25dfc0 posix: workaround for os.path.realpath bug in Python 2.4.1 and before
Thomas Arendsen Hein <thomas@intevation.de>
parents: 15056
diff changeset
   306
            return os.path.realpath(path)
ab600a25dfc0 posix: workaround for os.path.realpath bug in Python 2.4.1 and before
Thomas Arendsen Hein <thomas@intevation.de>
parents: 15056
diff changeset
   307
        else:
ab600a25dfc0 posix: workaround for os.path.realpath bug in Python 2.4.1 and before
Thomas Arendsen Hein <thomas@intevation.de>
parents: 15056
diff changeset
   308
            return os.path.realpath('./' + path)
9238
40196d036a71 util: add realpath() for getting the 'true' path.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 9031
diff changeset
   309
else:
40196d036a71 util: add realpath() for getting the 'true' path.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 9031
diff changeset
   310
    # Fallback to the likely inadequate Python builtin function.
40196d036a71 util: add realpath() for getting the 'true' path.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 9031
diff changeset
   311
    realpath = os.path.realpath
40196d036a71 util: add realpath() for getting the 'true' path.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 9031
diff changeset
   312
15711
c51c9dc13a58 cygwin: add cygwin specific normcase logic
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15672
diff changeset
   313
if sys.platform == 'cygwin':
c51c9dc13a58 cygwin: add cygwin specific normcase logic
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15672
diff changeset
   314
    # workaround for cygwin, in which mount point part of path is
c51c9dc13a58 cygwin: add cygwin specific normcase logic
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15672
diff changeset
   315
    # treated as case sensitive, even though underlying NTFS is case
c51c9dc13a58 cygwin: add cygwin specific normcase logic
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15672
diff changeset
   316
    # insensitive.
c51c9dc13a58 cygwin: add cygwin specific normcase logic
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15672
diff changeset
   317
c51c9dc13a58 cygwin: add cygwin specific normcase logic
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15672
diff changeset
   318
    # default mount points
c51c9dc13a58 cygwin: add cygwin specific normcase logic
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15672
diff changeset
   319
    cygwinmountpoints = sorted([
c51c9dc13a58 cygwin: add cygwin specific normcase logic
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15672
diff changeset
   320
            "/usr/bin",
c51c9dc13a58 cygwin: add cygwin specific normcase logic
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15672
diff changeset
   321
            "/usr/lib",
c51c9dc13a58 cygwin: add cygwin specific normcase logic
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15672
diff changeset
   322
            "/cygdrive",
c51c9dc13a58 cygwin: add cygwin specific normcase logic
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15672
diff changeset
   323
            ], reverse=True)
c51c9dc13a58 cygwin: add cygwin specific normcase logic
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15672
diff changeset
   324
c51c9dc13a58 cygwin: add cygwin specific normcase logic
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15672
diff changeset
   325
    # use upper-ing as normcase as same as NTFS workaround
c51c9dc13a58 cygwin: add cygwin specific normcase logic
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15672
diff changeset
   326
    def normcase(path):
c51c9dc13a58 cygwin: add cygwin specific normcase logic
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15672
diff changeset
   327
        pathlen = len(path)
c51c9dc13a58 cygwin: add cygwin specific normcase logic
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15672
diff changeset
   328
        if (pathlen == 0) or (path[0] != os.sep):
c51c9dc13a58 cygwin: add cygwin specific normcase logic
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15672
diff changeset
   329
            # treat as relative
17203
0cb55b5c19a3 util, posix: eliminate encodinglower and encodingupper
Adrian Buehlmann <adrian@cadifra.com>
parents: 16726
diff changeset
   330
            return encoding.upper(path)
15711
c51c9dc13a58 cygwin: add cygwin specific normcase logic
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15672
diff changeset
   331
c51c9dc13a58 cygwin: add cygwin specific normcase logic
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15672
diff changeset
   332
        # to preserve case of mountpoint part
c51c9dc13a58 cygwin: add cygwin specific normcase logic
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15672
diff changeset
   333
        for mp in cygwinmountpoints:
c51c9dc13a58 cygwin: add cygwin specific normcase logic
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15672
diff changeset
   334
            if not path.startswith(mp):
c51c9dc13a58 cygwin: add cygwin specific normcase logic
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15672
diff changeset
   335
                continue
c51c9dc13a58 cygwin: add cygwin specific normcase logic
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15672
diff changeset
   336
c51c9dc13a58 cygwin: add cygwin specific normcase logic
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15672
diff changeset
   337
            mplen = len(mp)
c51c9dc13a58 cygwin: add cygwin specific normcase logic
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15672
diff changeset
   338
            if mplen == pathlen: # mount point itself
c51c9dc13a58 cygwin: add cygwin specific normcase logic
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15672
diff changeset
   339
                return mp
c51c9dc13a58 cygwin: add cygwin specific normcase logic
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15672
diff changeset
   340
            if path[mplen] == os.sep:
17203
0cb55b5c19a3 util, posix: eliminate encodinglower and encodingupper
Adrian Buehlmann <adrian@cadifra.com>
parents: 16726
diff changeset
   341
                return mp + encoding.upper(path[mplen:])
15711
c51c9dc13a58 cygwin: add cygwin specific normcase logic
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15672
diff changeset
   342
17203
0cb55b5c19a3 util, posix: eliminate encodinglower and encodingupper
Adrian Buehlmann <adrian@cadifra.com>
parents: 16726
diff changeset
   343
        return encoding.upper(path)
15711
c51c9dc13a58 cygwin: add cygwin specific normcase logic
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15672
diff changeset
   344
16240
95e45abe7e8e posix: ignore execution bit in cygwin (issue3301)
A. S. Budden <abudden@gmail.com>
parents: 15791
diff changeset
   345
    # Cygwin translates native ACLs to POSIX permissions,
95e45abe7e8e posix: ignore execution bit in cygwin (issue3301)
A. S. Budden <abudden@gmail.com>
parents: 15791
diff changeset
   346
    # but these translations are not supported by native
95e45abe7e8e posix: ignore execution bit in cygwin (issue3301)
A. S. Budden <abudden@gmail.com>
parents: 15791
diff changeset
   347
    # tools, so the exec bit tends to be set erroneously.
95e45abe7e8e posix: ignore execution bit in cygwin (issue3301)
A. S. Budden <abudden@gmail.com>
parents: 15791
diff changeset
   348
    # Therefore, disable executable bit access on Cygwin.
95e45abe7e8e posix: ignore execution bit in cygwin (issue3301)
A. S. Budden <abudden@gmail.com>
parents: 15791
diff changeset
   349
    def checkexec(path):
95e45abe7e8e posix: ignore execution bit in cygwin (issue3301)
A. S. Budden <abudden@gmail.com>
parents: 15791
diff changeset
   350
        return False
95e45abe7e8e posix: ignore execution bit in cygwin (issue3301)
A. S. Budden <abudden@gmail.com>
parents: 15791
diff changeset
   351
16241
60cc3a0d2249 posix: disable cygwin's symlink emulation
Matt Mackall <mpm@selenic.com>
parents: 16240
diff changeset
   352
    # Similarly, Cygwin's symlink emulation is likely to create
60cc3a0d2249 posix: disable cygwin's symlink emulation
Matt Mackall <mpm@selenic.com>
parents: 16240
diff changeset
   353
    # problems when Mercurial is used from both Cygwin and native
60cc3a0d2249 posix: disable cygwin's symlink emulation
Matt Mackall <mpm@selenic.com>
parents: 16240
diff changeset
   354
    # Windows, with other native tools, or on shared volumes
60cc3a0d2249 posix: disable cygwin's symlink emulation
Matt Mackall <mpm@selenic.com>
parents: 16240
diff changeset
   355
    def checklink(path):
60cc3a0d2249 posix: disable cygwin's symlink emulation
Matt Mackall <mpm@selenic.com>
parents: 16240
diff changeset
   356
        return False
60cc3a0d2249 posix: disable cygwin's symlink emulation
Matt Mackall <mpm@selenic.com>
parents: 16240
diff changeset
   357
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   358
def shellquote(s):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   359
    if os.sys.platform == 'OpenVMS':
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   360
        return '"%s"' % s
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   361
    else:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   362
        return "'%s'" % s.replace("'", "'\\''")
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   363
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   364
def quotecommand(cmd):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   365
    return cmd
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   366
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   367
def popen(command, mode='r'):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   368
    return os.popen(command, mode)
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   369
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   370
def testpid(pid):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   371
    '''return False if pid dead, True if running or not sure'''
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   372
    if os.sys.platform == 'OpenVMS':
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   373
        return True
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   374
    try:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   375
        os.kill(pid, 0)
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   376
        return True
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   377
    except OSError, inst:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   378
        return inst.errno != errno.ESRCH
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   379
14234
600e64004eb5 rename explain_exit to explainexit
Adrian Buehlmann <adrian@cadifra.com>
parents: 14233
diff changeset
   380
def explainexit(code):
9517
4368f582c806 util.system: Use subprocess instead of os.system
Mads Kiilerich <mads@kiilerich.com>
parents: 9238
diff changeset
   381
    """return a 2-tuple (desc, code) describing a subprocess status
4368f582c806 util.system: Use subprocess instead of os.system
Mads Kiilerich <mads@kiilerich.com>
parents: 9238
diff changeset
   382
    (codes from kill are negative - not os.system/wait encoding)"""
4368f582c806 util.system: Use subprocess instead of os.system
Mads Kiilerich <mads@kiilerich.com>
parents: 9238
diff changeset
   383
    if code >= 0:
4368f582c806 util.system: Use subprocess instead of os.system
Mads Kiilerich <mads@kiilerich.com>
parents: 9238
diff changeset
   384
        return _("exited with status %d") % code, code
4368f582c806 util.system: Use subprocess instead of os.system
Mads Kiilerich <mads@kiilerich.com>
parents: 9238
diff changeset
   385
    return _("killed by signal %d") % -code, -code
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   386
8657
3fa92c618624 posix: do not use fstat in isowner
Martin Geisler <mg@lazybytes.net>
parents: 8614
diff changeset
   387
def isowner(st):
3fa92c618624 posix: do not use fstat in isowner
Martin Geisler <mg@lazybytes.net>
parents: 8614
diff changeset
   388
    """Return True if the stat object st is from the current user."""
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   389
    return st.st_uid == os.getuid()
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   390
14271
4030630fb59c rename util.find_exe to findexe
Adrian Buehlmann <adrian@cadifra.com>
parents: 14237
diff changeset
   391
def findexe(command):
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   392
    '''Find executable for command searching like which does.
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   393
    If command is a basename then PATH is searched for command.
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   394
    PATH isn't searched if command is an absolute or relative path.
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   395
    If command isn't found None is returned.'''
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   396
    if sys.platform == 'OpenVMS':
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   397
        return command
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   398
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   399
    def findexisting(executable):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   400
        'Will return executable if existing file'
15499
58f96703a9ab posix: fix findexe() to check for file type and access
Marc-Antoine Ruel <maruel@google.com>
parents: 15488
diff changeset
   401
        if os.path.isfile(executable) and os.access(executable, os.X_OK):
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   402
            return executable
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   403
        return None
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   404
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   405
    if os.sep in command:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   406
        return findexisting(command)
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   407
16383
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents: 16241
diff changeset
   408
    if sys.platform == 'plan9':
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents: 16241
diff changeset
   409
        return findexisting(os.path.join('/bin', command))
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents: 16241
diff changeset
   410
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   411
    for path in os.environ.get('PATH', '').split(os.pathsep):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   412
        executable = findexisting(os.path.join(path, command))
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   413
        if executable is not None:
15499
58f96703a9ab posix: fix findexe() to check for file type and access
Marc-Antoine Ruel <maruel@google.com>
parents: 15488
diff changeset
   414
            return executable
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   415
    return None
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   416
14237
4d684d8210a1 rename util.set_signal_handler to setsignalhandler
Adrian Buehlmann <adrian@cadifra.com>
parents: 14235
diff changeset
   417
def setsignalhandler():
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   418
    pass
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   419
18017
74912fe3d718 dirstate: move file type filtering to its source
Bryan O'Sullivan <bryano@fb.com>
parents: 17560
diff changeset
   420
_wantedkinds = set([stat.S_IFREG, stat.S_IFLNK])
74912fe3d718 dirstate: move file type filtering to its source
Bryan O'Sullivan <bryano@fb.com>
parents: 17560
diff changeset
   421
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   422
def statfiles(files):
18017
74912fe3d718 dirstate: move file type filtering to its source
Bryan O'Sullivan <bryano@fb.com>
parents: 17560
diff changeset
   423
    '''Stat each file in files. Yield each stat, or None if a file does not
74912fe3d718 dirstate: move file type filtering to its source
Bryan O'Sullivan <bryano@fb.com>
parents: 17560
diff changeset
   424
    exist or has a type we don't care about.'''
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   425
    lstat = os.lstat
18017
74912fe3d718 dirstate: move file type filtering to its source
Bryan O'Sullivan <bryano@fb.com>
parents: 17560
diff changeset
   426
    getkind = stat.S_IFMT
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   427
    for nf in files:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   428
        try:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   429
            st = lstat(nf)
18017
74912fe3d718 dirstate: move file type filtering to its source
Bryan O'Sullivan <bryano@fb.com>
parents: 17560
diff changeset
   430
            if getkind(st.st_mode) not in _wantedkinds:
74912fe3d718 dirstate: move file type filtering to its source
Bryan O'Sullivan <bryano@fb.com>
parents: 17560
diff changeset
   431
                st = None
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   432
        except OSError, err:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   433
            if err.errno not in (errno.ENOENT, errno.ENOTDIR):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   434
                raise
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   435
            st = None
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   436
        yield st
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   437
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   438
def getuser():
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   439
    '''return name of current user'''
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   440
    return getpass.getuser()
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   441
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   442
def username(uid=None):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   443
    """Return the name of the user with the given uid.
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   444
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   445
    If uid is None, return the name of the current user."""
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   446
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   447
    if uid is None:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   448
        uid = os.getuid()
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   449
    try:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   450
        return pwd.getpwuid(uid)[0]
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   451
    except KeyError:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   452
        return str(uid)
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   453
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   454
def groupname(gid=None):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   455
    """Return the name of the group with the given gid.
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   456
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   457
    If gid is None, return the name of the current group."""
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   458
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   459
    if gid is None:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   460
        gid = os.getgid()
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   461
    try:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   462
        return grp.getgrgid(gid)[0]
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   463
    except KeyError:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   464
        return str(gid)
10237
2f7a38f336f4 serve: add and use portable spawnvp replacement
Patrick Mezard <pmezard@gmail.com>
parents: 10218
diff changeset
   465
11138
99eee847beaa acl: grp module is not available on windows
Patrick Mezard <pmezard@gmail.com>
parents: 11011
diff changeset
   466
def groupmembers(name):
99eee847beaa acl: grp module is not available on windows
Patrick Mezard <pmezard@gmail.com>
parents: 11011
diff changeset
   467
    """Return the list of members of the group with the given
99eee847beaa acl: grp module is not available on windows
Patrick Mezard <pmezard@gmail.com>
parents: 11011
diff changeset
   468
    name, KeyError if the group does not exist.
99eee847beaa acl: grp module is not available on windows
Patrick Mezard <pmezard@gmail.com>
parents: 11011
diff changeset
   469
    """
99eee847beaa acl: grp module is not available on windows
Patrick Mezard <pmezard@gmail.com>
parents: 11011
diff changeset
   470
    return list(grp.getgrnam(name).gr_mem)
99eee847beaa acl: grp module is not available on windows
Patrick Mezard <pmezard@gmail.com>
parents: 11011
diff changeset
   471
10237
2f7a38f336f4 serve: add and use portable spawnvp replacement
Patrick Mezard <pmezard@gmail.com>
parents: 10218
diff changeset
   472
def spawndetached(args):
2f7a38f336f4 serve: add and use portable spawnvp replacement
Patrick Mezard <pmezard@gmail.com>
parents: 10218
diff changeset
   473
    return os.spawnvp(os.P_NOWAIT | getattr(os, 'P_DETACH', 0),
2f7a38f336f4 serve: add and use portable spawnvp replacement
Patrick Mezard <pmezard@gmail.com>
parents: 10218
diff changeset
   474
                      args[0], args)
2f7a38f336f4 serve: add and use portable spawnvp replacement
Patrick Mezard <pmezard@gmail.com>
parents: 10218
diff changeset
   475
10239
8e4be44a676f Find right hg command for detached process
Patrick Mezard <pmezard@gmail.com>
parents: 10237
diff changeset
   476
def gethgcmd():
8e4be44a676f Find right hg command for detached process
Patrick Mezard <pmezard@gmail.com>
parents: 10237
diff changeset
   477
    return sys.argv[:1]
11010
18e81d42ee5c util: fix default termwidth() under Windows
Patrick Mezard <pmezard@gmail.com>
parents: 10264
diff changeset
   478
12689
c52c629ce19e termwidth: move to ui.ui from util
Augie Fackler <durin42@gmail.com>
parents: 11138
diff changeset
   479
def termwidth():
11010
18e81d42ee5c util: fix default termwidth() under Windows
Patrick Mezard <pmezard@gmail.com>
parents: 10264
diff changeset
   480
    try:
18e81d42ee5c util: fix default termwidth() under Windows
Patrick Mezard <pmezard@gmail.com>
parents: 10264
diff changeset
   481
        import termios, array, fcntl
18e81d42ee5c util: fix default termwidth() under Windows
Patrick Mezard <pmezard@gmail.com>
parents: 10264
diff changeset
   482
        for dev in (sys.stderr, sys.stdout, sys.stdin):
18e81d42ee5c util: fix default termwidth() under Windows
Patrick Mezard <pmezard@gmail.com>
parents: 10264
diff changeset
   483
            try:
18e81d42ee5c util: fix default termwidth() under Windows
Patrick Mezard <pmezard@gmail.com>
parents: 10264
diff changeset
   484
                try:
18e81d42ee5c util: fix default termwidth() under Windows
Patrick Mezard <pmezard@gmail.com>
parents: 10264
diff changeset
   485
                    fd = dev.fileno()
18e81d42ee5c util: fix default termwidth() under Windows
Patrick Mezard <pmezard@gmail.com>
parents: 10264
diff changeset
   486
                except AttributeError:
18e81d42ee5c util: fix default termwidth() under Windows
Patrick Mezard <pmezard@gmail.com>
parents: 10264
diff changeset
   487
                    continue
18e81d42ee5c util: fix default termwidth() under Windows
Patrick Mezard <pmezard@gmail.com>
parents: 10264
diff changeset
   488
                if not os.isatty(fd):
18e81d42ee5c util: fix default termwidth() under Windows
Patrick Mezard <pmezard@gmail.com>
parents: 10264
diff changeset
   489
                    continue
16726
7002bb17cc5e posix: workaround lack of TIOCGWINSZ on Irix (issue3449)
Mark Round <hg@markround.com>
parents: 16383
diff changeset
   490
                try:
7002bb17cc5e posix: workaround lack of TIOCGWINSZ on Irix (issue3449)
Mark Round <hg@markround.com>
parents: 16383
diff changeset
   491
                    arri = fcntl.ioctl(fd, termios.TIOCGWINSZ, '\0' * 8)
7002bb17cc5e posix: workaround lack of TIOCGWINSZ on Irix (issue3449)
Mark Round <hg@markround.com>
parents: 16383
diff changeset
   492
                    width = array.array('h', arri)[1]
7002bb17cc5e posix: workaround lack of TIOCGWINSZ on Irix (issue3449)
Mark Round <hg@markround.com>
parents: 16383
diff changeset
   493
                    if width > 0:
7002bb17cc5e posix: workaround lack of TIOCGWINSZ on Irix (issue3449)
Mark Round <hg@markround.com>
parents: 16383
diff changeset
   494
                        return width
7002bb17cc5e posix: workaround lack of TIOCGWINSZ on Irix (issue3449)
Mark Round <hg@markround.com>
parents: 16383
diff changeset
   495
                except AttributeError:
7002bb17cc5e posix: workaround lack of TIOCGWINSZ on Irix (issue3449)
Mark Round <hg@markround.com>
parents: 16383
diff changeset
   496
                    pass
11010
18e81d42ee5c util: fix default termwidth() under Windows
Patrick Mezard <pmezard@gmail.com>
parents: 10264
diff changeset
   497
            except ValueError:
18e81d42ee5c util: fix default termwidth() under Windows
Patrick Mezard <pmezard@gmail.com>
parents: 10264
diff changeset
   498
                pass
18e81d42ee5c util: fix default termwidth() under Windows
Patrick Mezard <pmezard@gmail.com>
parents: 10264
diff changeset
   499
            except IOError, e:
18e81d42ee5c util: fix default termwidth() under Windows
Patrick Mezard <pmezard@gmail.com>
parents: 10264
diff changeset
   500
                if e[0] == errno.EINVAL:
18e81d42ee5c util: fix default termwidth() under Windows
Patrick Mezard <pmezard@gmail.com>
parents: 10264
diff changeset
   501
                    pass
18e81d42ee5c util: fix default termwidth() under Windows
Patrick Mezard <pmezard@gmail.com>
parents: 10264
diff changeset
   502
                else:
18e81d42ee5c util: fix default termwidth() under Windows
Patrick Mezard <pmezard@gmail.com>
parents: 10264
diff changeset
   503
                    raise
18e81d42ee5c util: fix default termwidth() under Windows
Patrick Mezard <pmezard@gmail.com>
parents: 10264
diff changeset
   504
    except ImportError:
18e81d42ee5c util: fix default termwidth() under Windows
Patrick Mezard <pmezard@gmail.com>
parents: 10264
diff changeset
   505
        pass
18e81d42ee5c util: fix default termwidth() under Windows
Patrick Mezard <pmezard@gmail.com>
parents: 10264
diff changeset
   506
    return 80
14908
e2b5605501df util: move "default" makedir to posix.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 14273
diff changeset
   507
e2b5605501df util: move "default" makedir to posix.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 14273
diff changeset
   508
def makedir(path, notindexed):
e2b5605501df util: move "default" makedir to posix.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 14273
diff changeset
   509
    os.mkdir(path)
14909
c627fe32c923 util: move "default" unlinkpath to posix.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 14908
diff changeset
   510
18143
242d2f4ec01c util: fold ENOENT check into unlinkpath, controlled by new ignoremissing flag
Mads Kiilerich <madski@unity3d.com>
parents: 18097
diff changeset
   511
def unlinkpath(f, ignoremissing=False):
14909
c627fe32c923 util: move "default" unlinkpath to posix.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 14908
diff changeset
   512
    """unlink and remove the directory if it is empty"""
18143
242d2f4ec01c util: fold ENOENT check into unlinkpath, controlled by new ignoremissing flag
Mads Kiilerich <madski@unity3d.com>
parents: 18097
diff changeset
   513
    try:
242d2f4ec01c util: fold ENOENT check into unlinkpath, controlled by new ignoremissing flag
Mads Kiilerich <madski@unity3d.com>
parents: 18097
diff changeset
   514
        os.unlink(f)
242d2f4ec01c util: fold ENOENT check into unlinkpath, controlled by new ignoremissing flag
Mads Kiilerich <madski@unity3d.com>
parents: 18097
diff changeset
   515
    except OSError, e:
242d2f4ec01c util: fold ENOENT check into unlinkpath, controlled by new ignoremissing flag
Mads Kiilerich <madski@unity3d.com>
parents: 18097
diff changeset
   516
        if not (ignoremissing and e.errno == errno.ENOENT):
242d2f4ec01c util: fold ENOENT check into unlinkpath, controlled by new ignoremissing flag
Mads Kiilerich <madski@unity3d.com>
parents: 18097
diff changeset
   517
            raise
14909
c627fe32c923 util: move "default" unlinkpath to posix.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 14908
diff changeset
   518
    # try removing directories that might now be empty
c627fe32c923 util: move "default" unlinkpath to posix.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 14908
diff changeset
   519
    try:
c627fe32c923 util: move "default" unlinkpath to posix.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 14908
diff changeset
   520
        os.removedirs(os.path.dirname(f))
c627fe32c923 util: move "default" unlinkpath to posix.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 14908
diff changeset
   521
    except OSError:
c627fe32c923 util: move "default" unlinkpath to posix.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 14908
diff changeset
   522
        pass
c627fe32c923 util: move "default" unlinkpath to posix.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 14908
diff changeset
   523
14910
570ea0259b0a util: move "default" lookupreg to posix.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 14909
diff changeset
   524
def lookupreg(key, name=None, scope=None):
570ea0259b0a util: move "default" lookupreg to posix.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 14909
diff changeset
   525
    return None
14911
5b39503157fd util: move "default" hidewindow to posix.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 14910
diff changeset
   526
5b39503157fd util: move "default" hidewindow to posix.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 14910
diff changeset
   527
def hidewindow():
5b39503157fd util: move "default" hidewindow to posix.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 14910
diff changeset
   528
    """Hide current shell window.
5b39503157fd util: move "default" hidewindow to posix.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 14910
diff changeset
   529
5b39503157fd util: move "default" hidewindow to posix.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 14910
diff changeset
   530
    Used to hide the window opened when starting asynchronous
5b39503157fd util: move "default" hidewindow to posix.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 14910
diff changeset
   531
    child process under Windows, unneeded on other systems.
5b39503157fd util: move "default" hidewindow to posix.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 14910
diff changeset
   532
    """
5b39503157fd util: move "default" hidewindow to posix.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 14910
diff changeset
   533
    pass
14926
4e7e63fc685a util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents: 14911
diff changeset
   534
14927
2aa3e07b2f07 posix, windows: introduce cachestat
Idan Kamara <idankk86@gmail.com>
parents: 14926
diff changeset
   535
class cachestat(object):
2aa3e07b2f07 posix, windows: introduce cachestat
Idan Kamara <idankk86@gmail.com>
parents: 14926
diff changeset
   536
    def __init__(self, path):
2aa3e07b2f07 posix, windows: introduce cachestat
Idan Kamara <idankk86@gmail.com>
parents: 14926
diff changeset
   537
        self.stat = os.stat(path)
2aa3e07b2f07 posix, windows: introduce cachestat
Idan Kamara <idankk86@gmail.com>
parents: 14926
diff changeset
   538
2aa3e07b2f07 posix, windows: introduce cachestat
Idan Kamara <idankk86@gmail.com>
parents: 14926
diff changeset
   539
    def cacheable(self):
2aa3e07b2f07 posix, windows: introduce cachestat
Idan Kamara <idankk86@gmail.com>
parents: 14926
diff changeset
   540
        return bool(self.stat.st_ino)
2aa3e07b2f07 posix, windows: introduce cachestat
Idan Kamara <idankk86@gmail.com>
parents: 14926
diff changeset
   541
15791
a814f8fcc65a Use explicit integer division
Martin Geisler <mg@aragost.com>
parents: 15711
diff changeset
   542
    __hash__ = object.__hash__
a814f8fcc65a Use explicit integer division
Martin Geisler <mg@aragost.com>
parents: 15711
diff changeset
   543
14927
2aa3e07b2f07 posix, windows: introduce cachestat
Idan Kamara <idankk86@gmail.com>
parents: 14926
diff changeset
   544
    def __eq__(self, other):
2aa3e07b2f07 posix, windows: introduce cachestat
Idan Kamara <idankk86@gmail.com>
parents: 14926
diff changeset
   545
        try:
18442
ecba9b0e7672 posix: don't compare atime when determining if a file has changed
Siddharth Agarwal <sid0@fb.com>
parents: 18288
diff changeset
   546
            # Only dev, ino, size, mtime and atime are likely to change. Out
ecba9b0e7672 posix: don't compare atime when determining if a file has changed
Siddharth Agarwal <sid0@fb.com>
parents: 18288
diff changeset
   547
            # of these, we shouldn't compare atime but should compare the
ecba9b0e7672 posix: don't compare atime when determining if a file has changed
Siddharth Agarwal <sid0@fb.com>
parents: 18288
diff changeset
   548
            # rest. However, one of the other fields changing indicates
ecba9b0e7672 posix: don't compare atime when determining if a file has changed
Siddharth Agarwal <sid0@fb.com>
parents: 18288
diff changeset
   549
            # something fishy going on, so return False if anything but atime
ecba9b0e7672 posix: don't compare atime when determining if a file has changed
Siddharth Agarwal <sid0@fb.com>
parents: 18288
diff changeset
   550
            # changes.
ecba9b0e7672 posix: don't compare atime when determining if a file has changed
Siddharth Agarwal <sid0@fb.com>
parents: 18288
diff changeset
   551
            return (self.stat.st_mode == other.stat.st_mode and
ecba9b0e7672 posix: don't compare atime when determining if a file has changed
Siddharth Agarwal <sid0@fb.com>
parents: 18288
diff changeset
   552
                    self.stat.st_ino == other.stat.st_ino and
ecba9b0e7672 posix: don't compare atime when determining if a file has changed
Siddharth Agarwal <sid0@fb.com>
parents: 18288
diff changeset
   553
                    self.stat.st_dev == other.stat.st_dev and
ecba9b0e7672 posix: don't compare atime when determining if a file has changed
Siddharth Agarwal <sid0@fb.com>
parents: 18288
diff changeset
   554
                    self.stat.st_nlink == other.stat.st_nlink and
ecba9b0e7672 posix: don't compare atime when determining if a file has changed
Siddharth Agarwal <sid0@fb.com>
parents: 18288
diff changeset
   555
                    self.stat.st_uid == other.stat.st_uid and
ecba9b0e7672 posix: don't compare atime when determining if a file has changed
Siddharth Agarwal <sid0@fb.com>
parents: 18288
diff changeset
   556
                    self.stat.st_gid == other.stat.st_gid and
ecba9b0e7672 posix: don't compare atime when determining if a file has changed
Siddharth Agarwal <sid0@fb.com>
parents: 18288
diff changeset
   557
                    self.stat.st_size == other.stat.st_size and
ecba9b0e7672 posix: don't compare atime when determining if a file has changed
Siddharth Agarwal <sid0@fb.com>
parents: 18288
diff changeset
   558
                    self.stat.st_mtime == other.stat.st_mtime and
ecba9b0e7672 posix: don't compare atime when determining if a file has changed
Siddharth Agarwal <sid0@fb.com>
parents: 18288
diff changeset
   559
                    self.stat.st_ctime == other.stat.st_ctime)
14927
2aa3e07b2f07 posix, windows: introduce cachestat
Idan Kamara <idankk86@gmail.com>
parents: 14926
diff changeset
   560
        except AttributeError:
2aa3e07b2f07 posix, windows: introduce cachestat
Idan Kamara <idankk86@gmail.com>
parents: 14926
diff changeset
   561
            return False
2aa3e07b2f07 posix, windows: introduce cachestat
Idan Kamara <idankk86@gmail.com>
parents: 14926
diff changeset
   562
2aa3e07b2f07 posix, windows: introduce cachestat
Idan Kamara <idankk86@gmail.com>
parents: 14926
diff changeset
   563
    def __ne__(self, other):
2aa3e07b2f07 posix, windows: introduce cachestat
Idan Kamara <idankk86@gmail.com>
parents: 14926
diff changeset
   564
        return not self == other
2aa3e07b2f07 posix, windows: introduce cachestat
Idan Kamara <idankk86@gmail.com>
parents: 14926
diff changeset
   565
14926
4e7e63fc685a util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents: 14911
diff changeset
   566
def executablepath():
4e7e63fc685a util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents: 14911
diff changeset
   567
    return None # available on Windows only
18097
ae54cff742e2 posix: move server side of unix domain sockets out of inotify
Bryan O'Sullivan <bryano@fb.com>
parents: 18017
diff changeset
   568
ae54cff742e2 posix: move server side of unix domain sockets out of inotify
Bryan O'Sullivan <bryano@fb.com>
parents: 18017
diff changeset
   569
class unixdomainserver(socket.socket):
ae54cff742e2 posix: move server side of unix domain sockets out of inotify
Bryan O'Sullivan <bryano@fb.com>
parents: 18017
diff changeset
   570
    def __init__(self, join, subsystem):
ae54cff742e2 posix: move server side of unix domain sockets out of inotify
Bryan O'Sullivan <bryano@fb.com>
parents: 18017
diff changeset
   571
        '''Create a unix domain socket with the given prefix.'''
ae54cff742e2 posix: move server side of unix domain sockets out of inotify
Bryan O'Sullivan <bryano@fb.com>
parents: 18017
diff changeset
   572
        super(unixdomainserver, self).__init__(socket.AF_UNIX)
ae54cff742e2 posix: move server side of unix domain sockets out of inotify
Bryan O'Sullivan <bryano@fb.com>
parents: 18017
diff changeset
   573
        sockname = subsystem + '.sock'
ae54cff742e2 posix: move server side of unix domain sockets out of inotify
Bryan O'Sullivan <bryano@fb.com>
parents: 18017
diff changeset
   574
        self.realpath = self.path = join(sockname)
ae54cff742e2 posix: move server side of unix domain sockets out of inotify
Bryan O'Sullivan <bryano@fb.com>
parents: 18017
diff changeset
   575
        if os.path.islink(self.path):
ae54cff742e2 posix: move server side of unix domain sockets out of inotify
Bryan O'Sullivan <bryano@fb.com>
parents: 18017
diff changeset
   576
            if os.path.exists(self.path):
ae54cff742e2 posix: move server side of unix domain sockets out of inotify
Bryan O'Sullivan <bryano@fb.com>
parents: 18017
diff changeset
   577
                self.realpath = os.readlink(self.path)
ae54cff742e2 posix: move server side of unix domain sockets out of inotify
Bryan O'Sullivan <bryano@fb.com>
parents: 18017
diff changeset
   578
            else:
ae54cff742e2 posix: move server side of unix domain sockets out of inotify
Bryan O'Sullivan <bryano@fb.com>
parents: 18017
diff changeset
   579
                os.unlink(self.path)
ae54cff742e2 posix: move server side of unix domain sockets out of inotify
Bryan O'Sullivan <bryano@fb.com>
parents: 18017
diff changeset
   580
        try:
ae54cff742e2 posix: move server side of unix domain sockets out of inotify
Bryan O'Sullivan <bryano@fb.com>
parents: 18017
diff changeset
   581
            self.bind(self.realpath)
ae54cff742e2 posix: move server side of unix domain sockets out of inotify
Bryan O'Sullivan <bryano@fb.com>
parents: 18017
diff changeset
   582
        except socket.error, err:
ae54cff742e2 posix: move server side of unix domain sockets out of inotify
Bryan O'Sullivan <bryano@fb.com>
parents: 18017
diff changeset
   583
            if err.args[0] == 'AF_UNIX path too long':
ae54cff742e2 posix: move server side of unix domain sockets out of inotify
Bryan O'Sullivan <bryano@fb.com>
parents: 18017
diff changeset
   584
                tmpdir = tempfile.mkdtemp(prefix='hg-%s-' % subsystem)
ae54cff742e2 posix: move server side of unix domain sockets out of inotify
Bryan O'Sullivan <bryano@fb.com>
parents: 18017
diff changeset
   585
                self.realpath = os.path.join(tmpdir, sockname)
ae54cff742e2 posix: move server side of unix domain sockets out of inotify
Bryan O'Sullivan <bryano@fb.com>
parents: 18017
diff changeset
   586
                try:
ae54cff742e2 posix: move server side of unix domain sockets out of inotify
Bryan O'Sullivan <bryano@fb.com>
parents: 18017
diff changeset
   587
                    self.bind(self.realpath)
ae54cff742e2 posix: move server side of unix domain sockets out of inotify
Bryan O'Sullivan <bryano@fb.com>
parents: 18017
diff changeset
   588
                    os.symlink(self.realpath, self.path)
ae54cff742e2 posix: move server side of unix domain sockets out of inotify
Bryan O'Sullivan <bryano@fb.com>
parents: 18017
diff changeset
   589
                except (OSError, socket.error):
ae54cff742e2 posix: move server side of unix domain sockets out of inotify
Bryan O'Sullivan <bryano@fb.com>
parents: 18017
diff changeset
   590
                    self.cleanup()
ae54cff742e2 posix: move server side of unix domain sockets out of inotify
Bryan O'Sullivan <bryano@fb.com>
parents: 18017
diff changeset
   591
                    raise
ae54cff742e2 posix: move server side of unix domain sockets out of inotify
Bryan O'Sullivan <bryano@fb.com>
parents: 18017
diff changeset
   592
            else:
ae54cff742e2 posix: move server side of unix domain sockets out of inotify
Bryan O'Sullivan <bryano@fb.com>
parents: 18017
diff changeset
   593
                raise
ae54cff742e2 posix: move server side of unix domain sockets out of inotify
Bryan O'Sullivan <bryano@fb.com>
parents: 18017
diff changeset
   594
        self.listen(5)
ae54cff742e2 posix: move server side of unix domain sockets out of inotify
Bryan O'Sullivan <bryano@fb.com>
parents: 18017
diff changeset
   595
ae54cff742e2 posix: move server side of unix domain sockets out of inotify
Bryan O'Sullivan <bryano@fb.com>
parents: 18017
diff changeset
   596
    def cleanup(self):
ae54cff742e2 posix: move server side of unix domain sockets out of inotify
Bryan O'Sullivan <bryano@fb.com>
parents: 18017
diff changeset
   597
        def okayifmissing(f, path):
ae54cff742e2 posix: move server side of unix domain sockets out of inotify
Bryan O'Sullivan <bryano@fb.com>
parents: 18017
diff changeset
   598
            try:
ae54cff742e2 posix: move server side of unix domain sockets out of inotify
Bryan O'Sullivan <bryano@fb.com>
parents: 18017
diff changeset
   599
                f(path)
ae54cff742e2 posix: move server side of unix domain sockets out of inotify
Bryan O'Sullivan <bryano@fb.com>
parents: 18017
diff changeset
   600
            except OSError, err:
ae54cff742e2 posix: move server side of unix domain sockets out of inotify
Bryan O'Sullivan <bryano@fb.com>
parents: 18017
diff changeset
   601
                if err.errno != errno.ENOENT:
ae54cff742e2 posix: move server side of unix domain sockets out of inotify
Bryan O'Sullivan <bryano@fb.com>
parents: 18017
diff changeset
   602
                    raise
ae54cff742e2 posix: move server side of unix domain sockets out of inotify
Bryan O'Sullivan <bryano@fb.com>
parents: 18017
diff changeset
   603
ae54cff742e2 posix: move server side of unix domain sockets out of inotify
Bryan O'Sullivan <bryano@fb.com>
parents: 18017
diff changeset
   604
        okayifmissing(os.unlink, self.path)
ae54cff742e2 posix: move server side of unix domain sockets out of inotify
Bryan O'Sullivan <bryano@fb.com>
parents: 18017
diff changeset
   605
        if self.realpath != self.path:
ae54cff742e2 posix: move server side of unix domain sockets out of inotify
Bryan O'Sullivan <bryano@fb.com>
parents: 18017
diff changeset
   606
            okayifmissing(os.unlink, self.realpath)
ae54cff742e2 posix: move server side of unix domain sockets out of inotify
Bryan O'Sullivan <bryano@fb.com>
parents: 18017
diff changeset
   607
            okayifmissing(os.rmdir, os.path.dirname(self.realpath))
18868
cafa447a7d3b util: add functions to check symlink/exec bits
Bryan O'Sullivan <bryano@fb.com>
parents: 18501
diff changeset
   608
cafa447a7d3b util: add functions to check symlink/exec bits
Bryan O'Sullivan <bryano@fb.com>
parents: 18501
diff changeset
   609
def statislink(st):
cafa447a7d3b util: add functions to check symlink/exec bits
Bryan O'Sullivan <bryano@fb.com>
parents: 18501
diff changeset
   610
    '''check whether a stat result is a symlink'''
cafa447a7d3b util: add functions to check symlink/exec bits
Bryan O'Sullivan <bryano@fb.com>
parents: 18501
diff changeset
   611
    return st and stat.S_ISLNK(st.st_mode)
cafa447a7d3b util: add functions to check symlink/exec bits
Bryan O'Sullivan <bryano@fb.com>
parents: 18501
diff changeset
   612
cafa447a7d3b util: add functions to check symlink/exec bits
Bryan O'Sullivan <bryano@fb.com>
parents: 18501
diff changeset
   613
def statisexec(st):
cafa447a7d3b util: add functions to check symlink/exec bits
Bryan O'Sullivan <bryano@fb.com>
parents: 18501
diff changeset
   614
    '''check whether a stat result is an executable file'''
cafa447a7d3b util: add functions to check symlink/exec bits
Bryan O'Sullivan <bryano@fb.com>
parents: 18501
diff changeset
   615
    return st and (st.st_mode & 0100 != 0)