mercurial/posix.py
author Augie Fackler <augie@google.com>
Mon, 07 Sep 2020 15:20:31 -0400
changeset 45411 a42999f611ff
parent 44867 8e8fd938ca07
child 45717 755214a84b9d
permissions -rw-r--r--
merge with stable
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
25967
224a33452ed4 posix: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
     8
from __future__ import absolute_import
224a33452ed4 posix: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
     9
224a33452ed4 posix: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    10
import errno
224a33452ed4 posix: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    11
import fcntl
224a33452ed4 posix: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    12
import getpass
224a33452ed4 posix: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    13
import grp
224a33452ed4 posix: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    14
import os
224a33452ed4 posix: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    15
import pwd
224a33452ed4 posix: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    16
import re
25420
c2ec81891502 util: add a simple poll utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24692
diff changeset
    17
import select
25967
224a33452ed4 posix: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    18
import stat
224a33452ed4 posix: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    19
import sys
224a33452ed4 posix: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    20
import tempfile
224a33452ed4 posix: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    21
import unicodedata
224a33452ed4 posix: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    22
224a33452ed4 posix: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    23
from .i18n import _
43089
c59eb1560c44 py3: manually import getattr where it is needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43085
diff changeset
    24
from .pycompat import (
c59eb1560c44 py3: manually import getattr where it is needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43085
diff changeset
    25
    getattr,
c59eb1560c44 py3: manually import getattr where it is needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43085
diff changeset
    26
    open,
c59eb1560c44 py3: manually import getattr where it is needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43085
diff changeset
    27
)
25967
224a33452ed4 posix: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    28
from . import (
224a33452ed4 posix: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    29
    encoding,
33651
739cc0f9cbb4 ssh: ban any username@host or host that starts with - (SEC)
Augie Fackler <augie@google.com>
parents: 32721
diff changeset
    30
    error,
35509
beede158ea8a util: move getfstype() to the platform modules
Matt Harbison <matt_harbison@yahoo.com>
parents: 34647
diff changeset
    31
    policy,
30612
d623cc6b3742 py3: replace os.pathsep with pycompat.ospathsep
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30555
diff changeset
    32
    pycompat,
25967
224a33452ed4 posix: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    33
)
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    34
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43477
diff changeset
    35
osutil = policy.importmod('osutil')
35509
beede158ea8a util: move getfstype() to the platform modules
Matt Harbison <matt_harbison@yahoo.com>
parents: 34647
diff changeset
    36
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    37
normpath = os.path.normpath
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    38
samestat = os.path.samestat
27236
b0d90fef16b6 posix: work around "posix" systems without os.link available (issue4974)
Augie Fackler <augie@google.com>
parents: 26901
diff changeset
    39
try:
b0d90fef16b6 posix: work around "posix" systems without os.link available (issue4974)
Augie Fackler <augie@google.com>
parents: 26901
diff changeset
    40
    oslink = os.link
b0d90fef16b6 posix: work around "posix" systems without os.link available (issue4974)
Augie Fackler <augie@google.com>
parents: 26901
diff changeset
    41
except AttributeError:
b0d90fef16b6 posix: work around "posix" systems without os.link available (issue4974)
Augie Fackler <augie@google.com>
parents: 26901
diff changeset
    42
    # Some platforms build Python without os.link on systems that are
b0d90fef16b6 posix: work around "posix" systems without os.link available (issue4974)
Augie Fackler <augie@google.com>
parents: 26901
diff changeset
    43
    # vaguely unix-like but don't have hardlink support. For those
b0d90fef16b6 posix: work around "posix" systems without os.link available (issue4974)
Augie Fackler <augie@google.com>
parents: 26901
diff changeset
    44
    # poor souls, just say we tried and that it failed so we fall back
b0d90fef16b6 posix: work around "posix" systems without os.link available (issue4974)
Augie Fackler <augie@google.com>
parents: 26901
diff changeset
    45
    # to copies.
b0d90fef16b6 posix: work around "posix" systems without os.link available (issue4974)
Augie Fackler <augie@google.com>
parents: 26901
diff changeset
    46
    def oslink(src, dst):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
    47
        raise OSError(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    48
            errno.EINVAL, b'hardlinks not supported: %s to %s' % (src, dst)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
    49
        )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
    50
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
    51
39904
5fe0b880200e py3: convert os.readlink() path to native strings on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 38252
diff changeset
    52
readlink = os.readlink
13280
6052bbc7aabd reintroduces util.unlink, for POSIX and Windows.
Adrian Buehlmann <adrian@cadifra.com>
parents: 13007
diff changeset
    53
unlink = os.unlink
9549
8b8920209317 util: move rename into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 9517
diff changeset
    54
rename = os.rename
24692
144883a8d0d4 util: add removedirs as platform depending function
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24596
diff changeset
    55
removedirs = os.removedirs
8614
573734e7e6d0 cmdutils: Take over glob expansion duties from util
Matt Mackall <mpm@selenic.com>
parents: 8312
diff changeset
    56
expandglobs = False
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    57
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    58
umask = os.umask(0)
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    59
os.umask(umask)
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    60
42562
97ada9b8d51b posix: always seek to EOF when opening a file in append mode
Augie Fackler <augie@google.com>
parents: 41827
diff changeset
    61
if not pycompat.ispy3:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
    62
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43477
diff changeset
    63
    def posixfile(name, mode='r', buffering=-1):
42562
97ada9b8d51b posix: always seek to EOF when opening a file in append mode
Augie Fackler <augie@google.com>
parents: 41827
diff changeset
    64
        fp = open(name, mode=mode, buffering=buffering)
97ada9b8d51b posix: always seek to EOF when opening a file in append mode
Augie Fackler <augie@google.com>
parents: 41827
diff changeset
    65
        # The position when opening in append mode is implementation defined, so
97ada9b8d51b posix: always seek to EOF when opening a file in append mode
Augie Fackler <augie@google.com>
parents: 41827
diff changeset
    66
        # make it consistent by always seeking to the end.
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43477
diff changeset
    67
        if 'a' in mode:
42562
97ada9b8d51b posix: always seek to EOF when opening a file in append mode
Augie Fackler <augie@google.com>
parents: 41827
diff changeset
    68
            fp.seek(0, os.SEEK_END)
97ada9b8d51b posix: always seek to EOF when opening a file in append mode
Augie Fackler <augie@google.com>
parents: 41827
diff changeset
    69
        return fp
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
    70
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
    71
42562
97ada9b8d51b posix: always seek to EOF when opening a file in append mode
Augie Fackler <augie@google.com>
parents: 41827
diff changeset
    72
else:
97ada9b8d51b posix: always seek to EOF when opening a file in append mode
Augie Fackler <augie@google.com>
parents: 41827
diff changeset
    73
    # The underlying file object seeks as required in Python 3:
97ada9b8d51b posix: always seek to EOF when opening a file in append mode
Augie Fackler <augie@google.com>
parents: 41827
diff changeset
    74
    # https://github.com/python/cpython/blob/v3.7.3/Modules/_io/fileio.c#L474
97ada9b8d51b posix: always seek to EOF when opening a file in append mode
Augie Fackler <augie@google.com>
parents: 41827
diff changeset
    75
    posixfile = open
97ada9b8d51b posix: always seek to EOF when opening a file in append mode
Augie Fackler <augie@google.com>
parents: 41827
diff changeset
    76
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
    77
17560
9ee25d7b1aed util: implement a faster os.path.split for posix systems
Bryan O'Sullivan <bryano@fb.com>
parents: 17391
diff changeset
    78
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
    79
    '''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
    80
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
    81
    >>> import posixpath
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33659
diff changeset
    82
    >>> for f in [b'/absolute/path/to/file',
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33659
diff changeset
    83
    ...           b'relative/path/to/file',
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33659
diff changeset
    84
    ...           b'file_alone',
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33659
diff changeset
    85
    ...           b'path/to/directory/',
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33659
diff changeset
    86
    ...           b'/multiple/path//separators',
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33659
diff changeset
    87
    ...           b'/file_at_root',
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33659
diff changeset
    88
    ...           b'///multiple_leading_separators_at_root',
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33659
diff changeset
    89
    ...           b'']:
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
    90
    ...     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
    91
    '''
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    92
    ht = p.rsplit(b'/', 1)
17560
9ee25d7b1aed util: implement a faster os.path.split for posix systems
Bryan O'Sullivan <bryano@fb.com>
parents: 17391
diff changeset
    93
    if len(ht) == 1:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    94
        return b'', p
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    95
    nh = ht[0].rstrip(b'/')
17560
9ee25d7b1aed util: implement a faster os.path.split for posix systems
Bryan O'Sullivan <bryano@fb.com>
parents: 17391
diff changeset
    96
    if nh:
9ee25d7b1aed util: implement a faster os.path.split for posix systems
Bryan O'Sullivan <bryano@fb.com>
parents: 17391
diff changeset
    97
        return nh, ht[1]
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    98
    return ht[0] + b'/', ht[1]
17560
9ee25d7b1aed util: implement a faster os.path.split for posix systems
Bryan O'Sullivan <bryano@fb.com>
parents: 17391
diff changeset
    99
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   100
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   101
def openhardlinks():
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   102
    '''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
   103
    return True
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   104
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   105
13375
f1fa8f481c7c port win32.py to using the Python ctypes library
Adrian Buehlmann <adrian@cadifra.com>
parents: 13280
diff changeset
   106
def nlinks(name):
f1fa8f481c7c port win32.py to using the Python ctypes library
Adrian Buehlmann <adrian@cadifra.com>
parents: 13280
diff changeset
   107
    '''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
   108
    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
   109
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   110
14231
8abe4db2d162 rename util.parse_patch_output to parsepatchoutput
Adrian Buehlmann <adrian@cadifra.com>
parents: 14165
diff changeset
   111
def parsepatchoutput(output_line):
8761
0289f384e1e5 Generally replace "file name" with "filename" in help and comments.
timeless <timeless@gmail.com>
parents: 8657
diff changeset
   112
    """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
   113
    pf = output_line[14:]
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   114
    if pycompat.sysplatform == b'OpenVMS':
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   115
        if pf[0] == b'`':
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   116
            pf = pf[1:-1]  # Remove the quotes
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   117
    else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   118
        if pf.startswith(b"'") and pf.endswith(b"'") and b" " in pf:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   119
            pf = pf[1:-1]  # Remove the quotes
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   120
    return pf
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   121
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   122
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   123
def sshargs(sshcmd, host, user, port):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   124
    '''Build argument list for ssh'''
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   125
    args = user and (b"%s@%s" % (user, host)) or host
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   126
    if b'-' in args[:1]:
33651
739cc0f9cbb4 ssh: ban any username@host or host that starts with - (SEC)
Augie Fackler <augie@google.com>
parents: 32721
diff changeset
   127
        raise error.Abort(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   128
            _(b'illegal ssh hostname or username starting with -: %s') % args
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   129
        )
33659
8cb9e921ef8c ssh: quote parameters using shellquote (SEC)
Jun Wu <quark@fb.com>
parents: 33651
diff changeset
   130
    args = shellquote(args)
8cb9e921ef8c ssh: quote parameters using shellquote (SEC)
Jun Wu <quark@fb.com>
parents: 33651
diff changeset
   131
    if port:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   132
        args = b'-p %s %s' % (shellquote(port), args)
33659
8cb9e921ef8c ssh: quote parameters using shellquote (SEC)
Jun Wu <quark@fb.com>
parents: 33651
diff changeset
   133
    return args
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   134
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   135
14273
38af0f514134 rename util.is_exec to isexec
Adrian Buehlmann <adrian@cadifra.com>
parents: 14272
diff changeset
   136
def isexec(f):
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   137
    """check whether a file is executable"""
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   138
    return os.lstat(f).st_mode & 0o100 != 0
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   139
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   140
14232
df2399663392 rename util.set_flags to setflags
Adrian Buehlmann <adrian@cadifra.com>
parents: 14231
diff changeset
   141
def setflags(f, l, x):
32721
c2cb0de25120 chmod: create a new file when flags are set on a hardlinked file
Koen Van Hoof <koen.van_hoof@nokia.com>
parents: 32394
diff changeset
   142
    st = os.lstat(f)
c2cb0de25120 chmod: create a new file when flags are set on a hardlinked file
Koen Van Hoof <koen.van_hoof@nokia.com>
parents: 32394
diff changeset
   143
    s = st.st_mode
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   144
    if l:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   145
        if not stat.S_ISLNK(s):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   146
            # switch file to link
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   147
            fp = open(f, b'rb')
13400
14f3795a5ed7 explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 13375
diff changeset
   148
            data = fp.read()
14f3795a5ed7 explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 13375
diff changeset
   149
            fp.close()
31537
c6cbe5720353 posix: use local reference to unlink
Ryan McElroy <rmcelroy@fb.com>
parents: 31506
diff changeset
   150
            unlink(f)
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   151
            try:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   152
                os.symlink(data, f)
14004
97ed99d1f419 eliminate various naked except clauses
Idan Kamara <idankk86@gmail.com>
parents: 13986
diff changeset
   153
            except OSError:
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   154
                # failed to make a link, rewrite file
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   155
                fp = open(f, b"wb")
13400
14f3795a5ed7 explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 13375
diff changeset
   156
                fp.write(data)
14f3795a5ed7 explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 13375
diff changeset
   157
                fp.close()
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   158
        # no chmod needed at this point
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   159
        return
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   160
    if stat.S_ISLNK(s):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   161
        # switch link to file
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   162
        data = os.readlink(f)
31537
c6cbe5720353 posix: use local reference to unlink
Ryan McElroy <rmcelroy@fb.com>
parents: 31506
diff changeset
   163
        unlink(f)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   164
        fp = open(f, b"wb")
13400
14f3795a5ed7 explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 13375
diff changeset
   165
        fp.write(data)
14f3795a5ed7 explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 13375
diff changeset
   166
        fp.close()
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   167
        s = 0o666 & ~umask  # avoid restatting for chmod
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   168
25658
e93036747902 global: mass rewrite to use modern octal syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25420
diff changeset
   169
    sx = s & 0o100
32721
c2cb0de25120 chmod: create a new file when flags are set on a hardlinked file
Koen Van Hoof <koen.van_hoof@nokia.com>
parents: 32394
diff changeset
   170
    if st.st_nlink > 1 and bool(x) != bool(sx):
c2cb0de25120 chmod: create a new file when flags are set on a hardlinked file
Koen Van Hoof <koen.van_hoof@nokia.com>
parents: 32394
diff changeset
   171
        # the file is a hardlink, break it
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   172
        with open(f, b"rb") as fp:
32721
c2cb0de25120 chmod: create a new file when flags are set on a hardlinked file
Koen Van Hoof <koen.van_hoof@nokia.com>
parents: 32394
diff changeset
   173
            data = fp.read()
c2cb0de25120 chmod: create a new file when flags are set on a hardlinked file
Koen Van Hoof <koen.van_hoof@nokia.com>
parents: 32394
diff changeset
   174
        unlink(f)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   175
        with open(f, b"wb") as fp:
32721
c2cb0de25120 chmod: create a new file when flags are set on a hardlinked file
Koen Van Hoof <koen.van_hoof@nokia.com>
parents: 32394
diff changeset
   176
            fp.write(data)
c2cb0de25120 chmod: create a new file when flags are set on a hardlinked file
Koen Van Hoof <koen.van_hoof@nokia.com>
parents: 32394
diff changeset
   177
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   178
    if x and not sx:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   179
        # 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
   180
        # and obey umask.
25658
e93036747902 global: mass rewrite to use modern octal syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25420
diff changeset
   181
        os.chmod(f, s | (s & 0o444) >> 2 & ~umask)
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   182
    elif not x and sx:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   183
        # Turn off all +x bits
25658
e93036747902 global: mass rewrite to use modern octal syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25420
diff changeset
   184
        os.chmod(f, s & 0o666)
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   185
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   186
41289
593f6359681d update: fix edge-case with update.atomic-file and read-only files
Boris Feld <boris.feld@octobus.net>
parents: 40792
diff changeset
   187
def copymode(src, dst, mode=None, enforcewritable=False):
15011
5e44e4b3a0a3 util: move copymode into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 14927
diff changeset
   188
    '''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
   189
    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
   190
    using umask.'''
5e44e4b3a0a3 util: move copymode into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 14927
diff changeset
   191
    try:
25658
e93036747902 global: mass rewrite to use modern octal syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25420
diff changeset
   192
        st_mode = os.lstat(src).st_mode & 0o777
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25658
diff changeset
   193
    except OSError as inst:
15011
5e44e4b3a0a3 util: move copymode into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 14927
diff changeset
   194
        if inst.errno != errno.ENOENT:
5e44e4b3a0a3 util: move copymode into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 14927
diff changeset
   195
            raise
5e44e4b3a0a3 util: move copymode into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 14927
diff changeset
   196
        st_mode = mode
5e44e4b3a0a3 util: move copymode into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 14927
diff changeset
   197
        if st_mode is None:
5e44e4b3a0a3 util: move copymode into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 14927
diff changeset
   198
            st_mode = ~umask
25658
e93036747902 global: mass rewrite to use modern octal syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25420
diff changeset
   199
        st_mode &= 0o666
41289
593f6359681d update: fix edge-case with update.atomic-file and read-only files
Boris Feld <boris.feld@octobus.net>
parents: 40792
diff changeset
   200
593f6359681d update: fix edge-case with update.atomic-file and read-only files
Boris Feld <boris.feld@octobus.net>
parents: 40792
diff changeset
   201
    new_mode = st_mode
593f6359681d update: fix edge-case with update.atomic-file and read-only files
Boris Feld <boris.feld@octobus.net>
parents: 40792
diff changeset
   202
593f6359681d update: fix edge-case with update.atomic-file and read-only files
Boris Feld <boris.feld@octobus.net>
parents: 40792
diff changeset
   203
    if enforcewritable:
593f6359681d update: fix edge-case with update.atomic-file and read-only files
Boris Feld <boris.feld@octobus.net>
parents: 40792
diff changeset
   204
        new_mode |= stat.S_IWUSR
593f6359681d update: fix edge-case with update.atomic-file and read-only files
Boris Feld <boris.feld@octobus.net>
parents: 40792
diff changeset
   205
593f6359681d update: fix edge-case with update.atomic-file and read-only files
Boris Feld <boris.feld@octobus.net>
parents: 40792
diff changeset
   206
    os.chmod(dst, new_mode)
15011
5e44e4b3a0a3 util: move copymode into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 14927
diff changeset
   207
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   208
13879
5b0a3f6cbead util: move checkexec() to posix.py and return False on Windows
Adrian Buehlmann <adrian@cadifra.com>
parents: 13400
diff changeset
   209
def checkexec(path):
5b0a3f6cbead util: move checkexec() to posix.py and return False on Windows
Adrian Buehlmann <adrian@cadifra.com>
parents: 13400
diff changeset
   210
    """
5b0a3f6cbead util: move checkexec() to posix.py and return False on Windows
Adrian Buehlmann <adrian@cadifra.com>
parents: 13400
diff changeset
   211
    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
   212
5b0a3f6cbead util: move checkexec() to posix.py and return False on Windows
Adrian Buehlmann <adrian@cadifra.com>
parents: 13400
diff changeset
   213
    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
   214
    """
5b0a3f6cbead util: move checkexec() to posix.py and return False on Windows
Adrian Buehlmann <adrian@cadifra.com>
parents: 13400
diff changeset
   215
5b0a3f6cbead util: move checkexec() to posix.py and return False on Windows
Adrian Buehlmann <adrian@cadifra.com>
parents: 13400
diff changeset
   216
    # 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
   217
    # 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
   218
    # 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
   219
5b0a3f6cbead util: move checkexec() to posix.py and return False on Windows
Adrian Buehlmann <adrian@cadifra.com>
parents: 13400
diff changeset
   220
    try:
5b0a3f6cbead util: move checkexec() to posix.py and return False on Windows
Adrian Buehlmann <adrian@cadifra.com>
parents: 13400
diff changeset
   221
        EXECFLAGS = stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   222
        basedir = os.path.join(path, b'.hg')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   223
        cachedir = os.path.join(basedir, b'wcache')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   224
        storedir = os.path.join(basedir, b'store')
40670
bd0874977a5e checkexec: create destination directory if necessary
Boris Feld <boris.feld@octobus.net>
parents: 39904
diff changeset
   225
        if not os.path.exists(cachedir):
bd0874977a5e checkexec: create destination directory if necessary
Boris Feld <boris.feld@octobus.net>
parents: 39904
diff changeset
   226
            try:
bd0874977a5e checkexec: create destination directory if necessary
Boris Feld <boris.feld@octobus.net>
parents: 39904
diff changeset
   227
                # we want to create the 'cache' directory, not the '.hg' one.
bd0874977a5e checkexec: create destination directory if necessary
Boris Feld <boris.feld@octobus.net>
parents: 39904
diff changeset
   228
                # Automatically creating '.hg' directory could silently spawn
bd0874977a5e checkexec: create destination directory if necessary
Boris Feld <boris.feld@octobus.net>
parents: 39904
diff changeset
   229
                # invalid Mercurial repositories. That seems like a bad idea.
bd0874977a5e checkexec: create destination directory if necessary
Boris Feld <boris.feld@octobus.net>
parents: 39904
diff changeset
   230
                os.mkdir(cachedir)
bd0874977a5e checkexec: create destination directory if necessary
Boris Feld <boris.feld@octobus.net>
parents: 39904
diff changeset
   231
                if os.path.exists(storedir):
bd0874977a5e checkexec: create destination directory if necessary
Boris Feld <boris.feld@octobus.net>
parents: 39904
diff changeset
   232
                    copymode(storedir, cachedir)
bd0874977a5e checkexec: create destination directory if necessary
Boris Feld <boris.feld@octobus.net>
parents: 39904
diff changeset
   233
                else:
bd0874977a5e checkexec: create destination directory if necessary
Boris Feld <boris.feld@octobus.net>
parents: 39904
diff changeset
   234
                    copymode(basedir, cachedir)
bd0874977a5e checkexec: create destination directory if necessary
Boris Feld <boris.feld@octobus.net>
parents: 39904
diff changeset
   235
            except (IOError, OSError):
bd0874977a5e checkexec: create destination directory if necessary
Boris Feld <boris.feld@octobus.net>
parents: 39904
diff changeset
   236
                # we other fallback logic triggers
bd0874977a5e checkexec: create destination directory if necessary
Boris Feld <boris.feld@octobus.net>
parents: 39904
diff changeset
   237
                pass
30446
b324b4e431e5 posix: give checkexec a fast path; keep the check files and test read only
Mads Kiilerich <madski@unity3d.com>
parents: 30445
diff changeset
   238
        if os.path.isdir(cachedir):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   239
            checkisexec = os.path.join(cachedir, b'checkisexec')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   240
            checknoexec = os.path.join(cachedir, b'checknoexec')
30446
b324b4e431e5 posix: give checkexec a fast path; keep the check files and test read only
Mads Kiilerich <madski@unity3d.com>
parents: 30445
diff changeset
   241
b324b4e431e5 posix: give checkexec a fast path; keep the check files and test read only
Mads Kiilerich <madski@unity3d.com>
parents: 30445
diff changeset
   242
            try:
b324b4e431e5 posix: give checkexec a fast path; keep the check files and test read only
Mads Kiilerich <madski@unity3d.com>
parents: 30445
diff changeset
   243
                m = os.stat(checkisexec).st_mode
b324b4e431e5 posix: give checkexec a fast path; keep the check files and test read only
Mads Kiilerich <madski@unity3d.com>
parents: 30445
diff changeset
   244
            except OSError as e:
b324b4e431e5 posix: give checkexec a fast path; keep the check files and test read only
Mads Kiilerich <madski@unity3d.com>
parents: 30445
diff changeset
   245
                if e.errno != errno.ENOENT:
b324b4e431e5 posix: give checkexec a fast path; keep the check files and test read only
Mads Kiilerich <madski@unity3d.com>
parents: 30445
diff changeset
   246
                    raise
b324b4e431e5 posix: give checkexec a fast path; keep the check files and test read only
Mads Kiilerich <madski@unity3d.com>
parents: 30445
diff changeset
   247
                # checkisexec does not exist - fall through ...
b324b4e431e5 posix: give checkexec a fast path; keep the check files and test read only
Mads Kiilerich <madski@unity3d.com>
parents: 30445
diff changeset
   248
            else:
b324b4e431e5 posix: give checkexec a fast path; keep the check files and test read only
Mads Kiilerich <madski@unity3d.com>
parents: 30445
diff changeset
   249
                # checkisexec exists, check if it actually is exec
b324b4e431e5 posix: give checkexec a fast path; keep the check files and test read only
Mads Kiilerich <madski@unity3d.com>
parents: 30445
diff changeset
   250
                if m & EXECFLAGS != 0:
b324b4e431e5 posix: give checkexec a fast path; keep the check files and test read only
Mads Kiilerich <madski@unity3d.com>
parents: 30445
diff changeset
   251
                    # ensure checkisexec exists, check it isn't exec
b324b4e431e5 posix: give checkexec a fast path; keep the check files and test read only
Mads Kiilerich <madski@unity3d.com>
parents: 30445
diff changeset
   252
                    try:
b324b4e431e5 posix: give checkexec a fast path; keep the check files and test read only
Mads Kiilerich <madski@unity3d.com>
parents: 30445
diff changeset
   253
                        m = os.stat(checknoexec).st_mode
b324b4e431e5 posix: give checkexec a fast path; keep the check files and test read only
Mads Kiilerich <madski@unity3d.com>
parents: 30445
diff changeset
   254
                    except OSError as e:
b324b4e431e5 posix: give checkexec a fast path; keep the check files and test read only
Mads Kiilerich <madski@unity3d.com>
parents: 30445
diff changeset
   255
                        if e.errno != errno.ENOENT:
b324b4e431e5 posix: give checkexec a fast path; keep the check files and test read only
Mads Kiilerich <madski@unity3d.com>
parents: 30445
diff changeset
   256
                            raise
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   257
                        open(checknoexec, b'w').close()  # might fail
30446
b324b4e431e5 posix: give checkexec a fast path; keep the check files and test read only
Mads Kiilerich <madski@unity3d.com>
parents: 30445
diff changeset
   258
                        m = os.stat(checknoexec).st_mode
b324b4e431e5 posix: give checkexec a fast path; keep the check files and test read only
Mads Kiilerich <madski@unity3d.com>
parents: 30445
diff changeset
   259
                    if m & EXECFLAGS == 0:
b324b4e431e5 posix: give checkexec a fast path; keep the check files and test read only
Mads Kiilerich <madski@unity3d.com>
parents: 30445
diff changeset
   260
                        # check-exec is exec and check-no-exec is not exec
b324b4e431e5 posix: give checkexec a fast path; keep the check files and test read only
Mads Kiilerich <madski@unity3d.com>
parents: 30445
diff changeset
   261
                        return True
b324b4e431e5 posix: give checkexec a fast path; keep the check files and test read only
Mads Kiilerich <madski@unity3d.com>
parents: 30445
diff changeset
   262
                    # checknoexec exists but is exec - delete it
31537
c6cbe5720353 posix: use local reference to unlink
Ryan McElroy <rmcelroy@fb.com>
parents: 31506
diff changeset
   263
                    unlink(checknoexec)
30446
b324b4e431e5 posix: give checkexec a fast path; keep the check files and test read only
Mads Kiilerich <madski@unity3d.com>
parents: 30445
diff changeset
   264
                # checkisexec exists but is not exec - delete it
31537
c6cbe5720353 posix: use local reference to unlink
Ryan McElroy <rmcelroy@fb.com>
parents: 31506
diff changeset
   265
                unlink(checkisexec)
30446
b324b4e431e5 posix: give checkexec a fast path; keep the check files and test read only
Mads Kiilerich <madski@unity3d.com>
parents: 30445
diff changeset
   266
b324b4e431e5 posix: give checkexec a fast path; keep the check files and test read only
Mads Kiilerich <madski@unity3d.com>
parents: 30445
diff changeset
   267
            # check using one file, leave it as checkisexec
b324b4e431e5 posix: give checkexec a fast path; keep the check files and test read only
Mads Kiilerich <madski@unity3d.com>
parents: 30445
diff changeset
   268
            checkdir = cachedir
b324b4e431e5 posix: give checkexec a fast path; keep the check files and test read only
Mads Kiilerich <madski@unity3d.com>
parents: 30445
diff changeset
   269
        else:
b324b4e431e5 posix: give checkexec a fast path; keep the check files and test read only
Mads Kiilerich <madski@unity3d.com>
parents: 30445
diff changeset
   270
            # check directly in path and don't leave checkisexec behind
b324b4e431e5 posix: give checkexec a fast path; keep the check files and test read only
Mads Kiilerich <madski@unity3d.com>
parents: 30445
diff changeset
   271
            checkdir = path
b324b4e431e5 posix: give checkexec a fast path; keep the check files and test read only
Mads Kiilerich <madski@unity3d.com>
parents: 30445
diff changeset
   272
            checkisexec = None
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   273
        fh, fn = pycompat.mkstemp(dir=checkdir, prefix=b'hg-checkexec-')
13879
5b0a3f6cbead util: move checkexec() to posix.py and return False on Windows
Adrian Buehlmann <adrian@cadifra.com>
parents: 13400
diff changeset
   274
        try:
5b0a3f6cbead util: move checkexec() to posix.py and return False on Windows
Adrian Buehlmann <adrian@cadifra.com>
parents: 13400
diff changeset
   275
            os.close(fh)
30445
1ce4c2062ab0 posix: simplify checkexec check
Mads Kiilerich <madski@unity3d.com>
parents: 30444
diff changeset
   276
            m = os.stat(fn).st_mode
30446
b324b4e431e5 posix: give checkexec a fast path; keep the check files and test read only
Mads Kiilerich <madski@unity3d.com>
parents: 30445
diff changeset
   277
            if m & EXECFLAGS == 0:
b324b4e431e5 posix: give checkexec a fast path; keep the check files and test read only
Mads Kiilerich <madski@unity3d.com>
parents: 30445
diff changeset
   278
                os.chmod(fn, m & 0o777 | EXECFLAGS)
b324b4e431e5 posix: give checkexec a fast path; keep the check files and test read only
Mads Kiilerich <madski@unity3d.com>
parents: 30445
diff changeset
   279
                if os.stat(fn).st_mode & EXECFLAGS != 0:
b324b4e431e5 posix: give checkexec a fast path; keep the check files and test read only
Mads Kiilerich <madski@unity3d.com>
parents: 30445
diff changeset
   280
                    if checkisexec is not None:
b324b4e431e5 posix: give checkexec a fast path; keep the check files and test read only
Mads Kiilerich <madski@unity3d.com>
parents: 30445
diff changeset
   281
                        os.rename(fn, checkisexec)
b324b4e431e5 posix: give checkexec a fast path; keep the check files and test read only
Mads Kiilerich <madski@unity3d.com>
parents: 30445
diff changeset
   282
                        fn = None
b324b4e431e5 posix: give checkexec a fast path; keep the check files and test read only
Mads Kiilerich <madski@unity3d.com>
parents: 30445
diff changeset
   283
                    return True
13879
5b0a3f6cbead util: move checkexec() to posix.py and return False on Windows
Adrian Buehlmann <adrian@cadifra.com>
parents: 13400
diff changeset
   284
        finally:
30446
b324b4e431e5 posix: give checkexec a fast path; keep the check files and test read only
Mads Kiilerich <madski@unity3d.com>
parents: 30445
diff changeset
   285
            if fn is not None:
31537
c6cbe5720353 posix: use local reference to unlink
Ryan McElroy <rmcelroy@fb.com>
parents: 31506
diff changeset
   286
                unlink(fn)
13879
5b0a3f6cbead util: move checkexec() to posix.py and return False on Windows
Adrian Buehlmann <adrian@cadifra.com>
parents: 13400
diff changeset
   287
    except (IOError, OSError):
5b0a3f6cbead util: move checkexec() to posix.py and return False on Windows
Adrian Buehlmann <adrian@cadifra.com>
parents: 13400
diff changeset
   288
        # 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
   289
        return False
5b0a3f6cbead util: move checkexec() to posix.py and return False on Windows
Adrian Buehlmann <adrian@cadifra.com>
parents: 13400
diff changeset
   290
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   291
13890
31eb145b50b6 util: move checklink() to posix.py and return False on Windows
Adrian Buehlmann <adrian@cadifra.com>
parents: 13879
diff changeset
   292
def checklink(path):
31eb145b50b6 util: move checklink() to posix.py and return False on Windows
Adrian Buehlmann <adrian@cadifra.com>
parents: 13879
diff changeset
   293
    """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
   294
    # 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
   295
    # file already exists
26883
c750ed59892a posix: retry on symlink race in checklink
Matt Mackall <mpm@selenic.com>
parents: 26248
diff changeset
   296
    while True:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   297
        cachedir = os.path.join(path, b'.hg', b'wcache')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   298
        checklink = os.path.join(cachedir, b'checklink')
30448
8836f13e3c5b posix: give checklink a fast path that cache the check file and is read only
Mads Kiilerich <madski@unity3d.com>
parents: 30447
diff changeset
   299
        # try fast path, read only
8836f13e3c5b posix: give checklink a fast path that cache the check file and is read only
Mads Kiilerich <madski@unity3d.com>
parents: 30447
diff changeset
   300
        if os.path.islink(checklink):
8836f13e3c5b posix: give checklink a fast path that cache the check file and is read only
Mads Kiilerich <madski@unity3d.com>
parents: 30447
diff changeset
   301
            return True
30447
0d87b1caed92 posix: move checklink test file to .hg/cache
Mads Kiilerich <madski@unity3d.com>
parents: 30446
diff changeset
   302
        if os.path.isdir(cachedir):
0d87b1caed92 posix: move checklink test file to .hg/cache
Mads Kiilerich <madski@unity3d.com>
parents: 30446
diff changeset
   303
            checkdir = cachedir
0d87b1caed92 posix: move checklink test file to .hg/cache
Mads Kiilerich <madski@unity3d.com>
parents: 30446
diff changeset
   304
        else:
0d87b1caed92 posix: move checklink test file to .hg/cache
Mads Kiilerich <madski@unity3d.com>
parents: 30446
diff changeset
   305
            checkdir = path
0d87b1caed92 posix: move checklink test file to .hg/cache
Mads Kiilerich <madski@unity3d.com>
parents: 30446
diff changeset
   306
            cachedir = None
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   307
        name = tempfile.mktemp(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   308
            dir=pycompat.fsdecode(checkdir), prefix=r'checklink-'
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   309
        )
31506
53575feed7c0 posix: tiptoe around tempfile module more delicately
Augie Fackler <augie@google.com>
parents: 31505
diff changeset
   310
        name = pycompat.fsencode(name)
22946
77c121da6143 checklink: always close the NamedTemporaryFile
Augie Fackler <raf@durin42.com>
parents: 22781
diff changeset
   311
        try:
30555
6a672c3b7860 posix: give the cached symlink a real target
Martijn Pieters <mjpieters@fb.com>
parents: 30448
diff changeset
   312
            fd = None
6a672c3b7860 posix: give the cached symlink a real target
Martijn Pieters <mjpieters@fb.com>
parents: 30448
diff changeset
   313
            if cachedir is None:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   314
                fd = pycompat.namedtempfile(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   315
                    dir=checkdir, prefix=b'hg-checklink-'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   316
                )
38166
cc9aa88792fe py3: wrap tempfile.NamedTemporaryFile() to return bytes fp.name
Yuya Nishihara <yuya@tcha.org>
parents: 38164
diff changeset
   317
                target = os.path.basename(fd.name)
30555
6a672c3b7860 posix: give the cached symlink a real target
Martijn Pieters <mjpieters@fb.com>
parents: 30448
diff changeset
   318
            else:
6a672c3b7860 posix: give the cached symlink a real target
Martijn Pieters <mjpieters@fb.com>
parents: 30448
diff changeset
   319
                # create a fixed file to link to; doesn't matter if it
6a672c3b7860 posix: give the cached symlink a real target
Martijn Pieters <mjpieters@fb.com>
parents: 30448
diff changeset
   320
                # already exists.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   321
                target = b'checklink-target'
32394
38a2b9d90131 checklink: degrade gracefully on posix when fs is readonly (issue5511)
Augie Fackler <augie@google.com>
parents: 32291
diff changeset
   322
                try:
36948
0585337ea787 cleanup: fix some latent open(path).read() et al calls we previously missed
Augie Fackler <augie@google.com>
parents: 36781
diff changeset
   323
                    fullpath = os.path.join(cachedir, target)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   324
                    open(fullpath, b'w').close()
32394
38a2b9d90131 checklink: degrade gracefully on posix when fs is readonly (issue5511)
Augie Fackler <augie@google.com>
parents: 32291
diff changeset
   325
                except IOError as inst:
43477
147576a4e6a2 posix: add a pytype suppression
Augie Fackler <augie@google.com>
parents: 43089
diff changeset
   326
                    if (
44306
a0ec05d93c8e cleanup: re-run black on the codebase
Augie Fackler <augie@google.com>
parents: 43506
diff changeset
   327
                        inst[0] == errno.EACCES
a0ec05d93c8e cleanup: re-run black on the codebase
Augie Fackler <augie@google.com>
parents: 43506
diff changeset
   328
                    ):  # pytype: disable=unsupported-operands
32394
38a2b9d90131 checklink: degrade gracefully on posix when fs is readonly (issue5511)
Augie Fackler <augie@google.com>
parents: 32291
diff changeset
   329
                        # If we can't write to cachedir, just pretend
38a2b9d90131 checklink: degrade gracefully on posix when fs is readonly (issue5511)
Augie Fackler <augie@google.com>
parents: 32291
diff changeset
   330
                        # that the fs is readonly and by association
38a2b9d90131 checklink: degrade gracefully on posix when fs is readonly (issue5511)
Augie Fackler <augie@google.com>
parents: 32291
diff changeset
   331
                        # that the fs won't support symlinks. This
38a2b9d90131 checklink: degrade gracefully on posix when fs is readonly (issue5511)
Augie Fackler <augie@google.com>
parents: 32291
diff changeset
   332
                        # seems like the least dangerous way to avoid
38a2b9d90131 checklink: degrade gracefully on posix when fs is readonly (issue5511)
Augie Fackler <augie@google.com>
parents: 32291
diff changeset
   333
                        # data loss.
38a2b9d90131 checklink: degrade gracefully on posix when fs is readonly (issue5511)
Augie Fackler <augie@google.com>
parents: 32291
diff changeset
   334
                        return False
38a2b9d90131 checklink: degrade gracefully on posix when fs is readonly (issue5511)
Augie Fackler <augie@google.com>
parents: 32291
diff changeset
   335
                    raise
26883
c750ed59892a posix: retry on symlink race in checklink
Matt Mackall <mpm@selenic.com>
parents: 26248
diff changeset
   336
            try:
30555
6a672c3b7860 posix: give the cached symlink a real target
Martijn Pieters <mjpieters@fb.com>
parents: 30448
diff changeset
   337
                os.symlink(target, name)
30448
8836f13e3c5b posix: give checklink a fast path that cache the check file and is read only
Mads Kiilerich <madski@unity3d.com>
parents: 30447
diff changeset
   338
                if cachedir is None:
31537
c6cbe5720353 posix: use local reference to unlink
Ryan McElroy <rmcelroy@fb.com>
parents: 31506
diff changeset
   339
                    unlink(name)
30448
8836f13e3c5b posix: give checklink a fast path that cache the check file and is read only
Mads Kiilerich <madski@unity3d.com>
parents: 30447
diff changeset
   340
                else:
8836f13e3c5b posix: give checklink a fast path that cache the check file and is read only
Mads Kiilerich <madski@unity3d.com>
parents: 30447
diff changeset
   341
                    try:
8836f13e3c5b posix: give checklink a fast path that cache the check file and is read only
Mads Kiilerich <madski@unity3d.com>
parents: 30447
diff changeset
   342
                        os.rename(name, checklink)
8836f13e3c5b posix: give checklink a fast path that cache the check file and is read only
Mads Kiilerich <madski@unity3d.com>
parents: 30447
diff changeset
   343
                    except OSError:
31537
c6cbe5720353 posix: use local reference to unlink
Ryan McElroy <rmcelroy@fb.com>
parents: 31506
diff changeset
   344
                        unlink(name)
26883
c750ed59892a posix: retry on symlink race in checklink
Matt Mackall <mpm@selenic.com>
parents: 26248
diff changeset
   345
                return True
c750ed59892a posix: retry on symlink race in checklink
Matt Mackall <mpm@selenic.com>
parents: 26248
diff changeset
   346
            except OSError as inst:
c750ed59892a posix: retry on symlink race in checklink
Matt Mackall <mpm@selenic.com>
parents: 26248
diff changeset
   347
                # link creation might race, try again
37934
2d919ab6c5b4 posix: use inst.errno instead of inst[0] on OSError instances
Augie Fackler <augie@google.com>
parents: 37460
diff changeset
   348
                if inst.errno == errno.EEXIST:
26883
c750ed59892a posix: retry on symlink race in checklink
Matt Mackall <mpm@selenic.com>
parents: 26248
diff changeset
   349
                    continue
26889
1aa5083cbebb posix: fix test-permissions regression
Matt Mackall <mpm@selenic.com>
parents: 26883
diff changeset
   350
                raise
26883
c750ed59892a posix: retry on symlink race in checklink
Matt Mackall <mpm@selenic.com>
parents: 26248
diff changeset
   351
            finally:
30555
6a672c3b7860 posix: give the cached symlink a real target
Martijn Pieters <mjpieters@fb.com>
parents: 30448
diff changeset
   352
                if fd is not None:
6a672c3b7860 posix: give the cached symlink a real target
Martijn Pieters <mjpieters@fb.com>
parents: 30448
diff changeset
   353
                    fd.close()
26883
c750ed59892a posix: retry on symlink race in checklink
Matt Mackall <mpm@selenic.com>
parents: 26248
diff changeset
   354
        except AttributeError:
c750ed59892a posix: retry on symlink race in checklink
Matt Mackall <mpm@selenic.com>
parents: 26248
diff changeset
   355
            return False
26889
1aa5083cbebb posix: fix test-permissions regression
Matt Mackall <mpm@selenic.com>
parents: 26883
diff changeset
   356
        except OSError as inst:
1aa5083cbebb posix: fix test-permissions regression
Matt Mackall <mpm@selenic.com>
parents: 26883
diff changeset
   357
            # sshfs might report failure while successfully creating the link
37934
2d919ab6c5b4 posix: use inst.errno instead of inst[0] on OSError instances
Augie Fackler <augie@google.com>
parents: 37460
diff changeset
   358
            if inst.errno == errno.EIO and os.path.exists(name):
31537
c6cbe5720353 posix: use local reference to unlink
Ryan McElroy <rmcelroy@fb.com>
parents: 31506
diff changeset
   359
                unlink(name)
26889
1aa5083cbebb posix: fix test-permissions regression
Matt Mackall <mpm@selenic.com>
parents: 26883
diff changeset
   360
            return False
13890
31eb145b50b6 util: move checklink() to posix.py and return False on Windows
Adrian Buehlmann <adrian@cadifra.com>
parents: 13879
diff changeset
   361
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   362
13916
98ee3dd5bab4 path_auditor: check filenames for basic platform validity (issue2755)
Adrian Buehlmann <adrian@cadifra.com>
parents: 13890
diff changeset
   363
def checkosfilename(path):
98ee3dd5bab4 path_auditor: check filenames for basic platform validity (issue2755)
Adrian Buehlmann <adrian@cadifra.com>
parents: 13890
diff changeset
   364
    '''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
   365
    Returns None if the path is ok, or a UI string describing the problem.'''
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   366
    return None  # on posix platforms, every path is ok
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   367
13916
98ee3dd5bab4 path_auditor: check filenames for basic platform validity (issue2755)
Adrian Buehlmann <adrian@cadifra.com>
parents: 13890
diff changeset
   368
35513
c4caf530b1c7 util: add a function to show the mount point of the filesystem
Matt Harbison <matt_harbison@yahoo.com>
parents: 35509
diff changeset
   369
def getfsmountpoint(dirpath):
c4caf530b1c7 util: add a function to show the mount point of the filesystem
Matt Harbison <matt_harbison@yahoo.com>
parents: 35509
diff changeset
   370
    '''Get the filesystem mount point from a directory (best-effort)
c4caf530b1c7 util: add a function to show the mount point of the filesystem
Matt Harbison <matt_harbison@yahoo.com>
parents: 35509
diff changeset
   371
c4caf530b1c7 util: add a function to show the mount point of the filesystem
Matt Harbison <matt_harbison@yahoo.com>
parents: 35509
diff changeset
   372
    Returns None if we are unsure. Raises OSError on ENOENT, EPERM, etc.
c4caf530b1c7 util: add a function to show the mount point of the filesystem
Matt Harbison <matt_harbison@yahoo.com>
parents: 35509
diff changeset
   373
    '''
c4caf530b1c7 util: add a function to show the mount point of the filesystem
Matt Harbison <matt_harbison@yahoo.com>
parents: 35509
diff changeset
   374
    return getattr(osutil, 'getfsmountpoint', lambda x: None)(dirpath)
c4caf530b1c7 util: add a function to show the mount point of the filesystem
Matt Harbison <matt_harbison@yahoo.com>
parents: 35509
diff changeset
   375
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   376
35509
beede158ea8a util: move getfstype() to the platform modules
Matt Harbison <matt_harbison@yahoo.com>
parents: 34647
diff changeset
   377
def getfstype(dirpath):
beede158ea8a util: move getfstype() to the platform modules
Matt Harbison <matt_harbison@yahoo.com>
parents: 34647
diff changeset
   378
    '''Get the filesystem type name from a directory (best-effort)
beede158ea8a util: move getfstype() to the platform modules
Matt Harbison <matt_harbison@yahoo.com>
parents: 34647
diff changeset
   379
beede158ea8a util: move getfstype() to the platform modules
Matt Harbison <matt_harbison@yahoo.com>
parents: 34647
diff changeset
   380
    Returns None if we are unsure. Raises OSError on ENOENT, EPERM, etc.
beede158ea8a util: move getfstype() to the platform modules
Matt Harbison <matt_harbison@yahoo.com>
parents: 34647
diff changeset
   381
    '''
beede158ea8a util: move getfstype() to the platform modules
Matt Harbison <matt_harbison@yahoo.com>
parents: 34647
diff changeset
   382
    return getattr(osutil, 'getfstype', lambda x: None)(dirpath)
beede158ea8a util: move getfstype() to the platform modules
Matt Harbison <matt_harbison@yahoo.com>
parents: 34647
diff changeset
   383
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   384
14233
659f34b833b9 rename util.set_binary to setbinary
Adrian Buehlmann <adrian@cadifra.com>
parents: 14232
diff changeset
   385
def setbinary(fd):
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   386
    pass
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   387
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   388
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   389
def pconvert(path):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   390
    return path
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   391
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   392
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   393
def localpath(path):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   394
    return path
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   395
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   396
10218
750b7a4f01f6 Add support for relinking on Windows.
Siddharth Agarwal <sid.bugzilla@gmail.com>
parents: 9549
diff changeset
   397
def samefile(fpath1, fpath2):
750b7a4f01f6 Add support for relinking on Windows.
Siddharth Agarwal <sid.bugzilla@gmail.com>
parents: 9549
diff changeset
   398
    """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
   399
    guaranteed to work for files, not directories."""
750b7a4f01f6 Add support for relinking on Windows.
Siddharth Agarwal <sid.bugzilla@gmail.com>
parents: 9549
diff changeset
   400
    return os.path.samefile(fpath1, fpath2)
750b7a4f01f6 Add support for relinking on Windows.
Siddharth Agarwal <sid.bugzilla@gmail.com>
parents: 9549
diff changeset
   401
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   402
10218
750b7a4f01f6 Add support for relinking on Windows.
Siddharth Agarwal <sid.bugzilla@gmail.com>
parents: 9549
diff changeset
   403
def samedevice(fpath1, fpath2):
750b7a4f01f6 Add support for relinking on Windows.
Siddharth Agarwal <sid.bugzilla@gmail.com>
parents: 9549
diff changeset
   404
    """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
   405
    guaranteed to work for files, not directories."""
750b7a4f01f6 Add support for relinking on Windows.
Siddharth Agarwal <sid.bugzilla@gmail.com>
parents: 9549
diff changeset
   406
    st1 = os.lstat(fpath1)
750b7a4f01f6 Add support for relinking on Windows.
Siddharth Agarwal <sid.bugzilla@gmail.com>
parents: 9549
diff changeset
   407
    st2 = os.lstat(fpath2)
750b7a4f01f6 Add support for relinking on Windows.
Siddharth Agarwal <sid.bugzilla@gmail.com>
parents: 9549
diff changeset
   408
    return st1.st_dev == st2.st_dev
750b7a4f01f6 Add support for relinking on Windows.
Siddharth Agarwal <sid.bugzilla@gmail.com>
parents: 9549
diff changeset
   409
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   410
15488
6eff984d8e76 dirstate: fix case-folding identity for traditional Unix
Matt Mackall <mpm@selenic.com>
parents: 15353
diff changeset
   411
# 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
   412
def normcase(path):
6eff984d8e76 dirstate: fix case-folding identity for traditional Unix
Matt Mackall <mpm@selenic.com>
parents: 15353
diff changeset
   413
    return path.lower()
6eff984d8e76 dirstate: fix case-folding identity for traditional Unix
Matt Mackall <mpm@selenic.com>
parents: 15353
diff changeset
   414
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   415
24594
609aa973c01d posix: define normcase spec and fallback
Siddharth Agarwal <sid0@fb.com>
parents: 24108
diff changeset
   416
# what normcase does to ASCII strings
609aa973c01d posix: define normcase spec and fallback
Siddharth Agarwal <sid0@fb.com>
parents: 24108
diff changeset
   417
normcasespec = encoding.normcasespecs.lower
609aa973c01d posix: define normcase spec and fallback
Siddharth Agarwal <sid0@fb.com>
parents: 24108
diff changeset
   418
# fallback normcase function for non-ASCII strings
609aa973c01d posix: define normcase spec and fallback
Siddharth Agarwal <sid0@fb.com>
parents: 24108
diff changeset
   419
normcasefallback = normcase
609aa973c01d posix: define normcase spec and fallback
Siddharth Agarwal <sid0@fb.com>
parents: 24108
diff changeset
   420
34647
dacfcdd8b94e codemod: use pycompat.isdarwin
Jun Wu <quark@fb.com>
parents: 34383
diff changeset
   421
if pycompat.isdarwin:
15551
1fa41d1f1351 posix: add extended support for OS X path folding
Matt Mackall <mpm@selenic.com>
parents: 15499
diff changeset
   422
1fa41d1f1351 posix: add extended support for OS X path folding
Matt Mackall <mpm@selenic.com>
parents: 15499
diff changeset
   423
    def normcase(path):
19131
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   424
        '''
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   425
        Normalize a filename for OS X-compatible comparison:
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   426
        - escape-encode invalid characters
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   427
        - decompose to NFD
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   428
        - lowercase
23597
7a5bcd471f2e darwin: omit ignorable codepoints when normcase()ing a file path
Augie Fackler <raf@durin42.com>
parents: 22946
diff changeset
   429
        - omit ignored characters [200c-200f, 202a-202e, 206a-206f,feff]
19131
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   430
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33659
diff changeset
   431
        >>> normcase(b'UPPER')
19131
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   432
        'upper'
34199
90b0e1639fd4 posix: fix HFS+ normcase doctest to produce valid bytes literals in Python 3
Augie Fackler <raf@durin42.com>
parents: 34131
diff changeset
   433
        >>> normcase(b'Caf\\xc3\\xa9')
19131
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   434
        'cafe\\xcc\\x81'
34199
90b0e1639fd4 posix: fix HFS+ normcase doctest to produce valid bytes literals in Python 3
Augie Fackler <raf@durin42.com>
parents: 34131
diff changeset
   435
        >>> normcase(b'\\xc3\\x89')
19131
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   436
        'e\\xcc\\x81'
34199
90b0e1639fd4 posix: fix HFS+ normcase doctest to produce valid bytes literals in Python 3
Augie Fackler <raf@durin42.com>
parents: 34131
diff changeset
   437
        >>> normcase(b'\\xb8\\xca\\xc3\\xca\\xbe\\xc8.JPG') # issue3918
19131
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   438
        '%b8%ca%c3\\xca\\xbe%c8.jpg'
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   439
        '''
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   440
15551
1fa41d1f1351 posix: add extended support for OS X path folding
Matt Mackall <mpm@selenic.com>
parents: 15499
diff changeset
   441
        try:
22781
70624fda193d normcase: for darwin, use fast ASCII lower
Siddharth Agarwal <sid0@fb.com>
parents: 22246
diff changeset
   442
            return encoding.asciilower(path)  # exception for non-ASCII
18501
a3b2dc1aa909 OS X: try cheap ascii .lower() in normcase before making full unicode dance
Mads Kiilerich <madski@unity3d.com>
parents: 18442
diff changeset
   443
        except UnicodeDecodeError:
24595
136ab89d61cb darwin: define normcase spec and fallback
Siddharth Agarwal <sid0@fb.com>
parents: 24594
diff changeset
   444
            return normcasefallback(path)
136ab89d61cb darwin: define normcase spec and fallback
Siddharth Agarwal <sid0@fb.com>
parents: 24594
diff changeset
   445
136ab89d61cb darwin: define normcase spec and fallback
Siddharth Agarwal <sid0@fb.com>
parents: 24594
diff changeset
   446
    normcasespec = encoding.normcasespecs.lower
136ab89d61cb darwin: define normcase spec and fallback
Siddharth Agarwal <sid0@fb.com>
parents: 24594
diff changeset
   447
136ab89d61cb darwin: define normcase spec and fallback
Siddharth Agarwal <sid0@fb.com>
parents: 24594
diff changeset
   448
    def normcasefallback(path):
18501
a3b2dc1aa909 OS X: try cheap ascii .lower() in normcase before making full unicode dance
Mads Kiilerich <madski@unity3d.com>
parents: 18442
diff changeset
   449
        try:
15551
1fa41d1f1351 posix: add extended support for OS X path folding
Matt Mackall <mpm@selenic.com>
parents: 15499
diff changeset
   450
            u = path.decode('utf-8')
1fa41d1f1351 posix: add extended support for OS X path folding
Matt Mackall <mpm@selenic.com>
parents: 15499
diff changeset
   451
        except UnicodeDecodeError:
19131
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   452
            # OS X percent-encodes any bytes that aren't valid utf-8
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   453
            s = b''
26876
b8381832ce2b posix: use getutf8char to handle OS X filename percent-escaping
Matt Mackall <mpm@selenic.com>
parents: 26248
diff changeset
   454
            pos = 0
27380
c7129ed280b8 mac: fix percent-encoding of non-utf-8 characters (issue4999)
Matt Mackall <mpm@selenic.com>
parents: 27362
diff changeset
   455
            l = len(path)
26876
b8381832ce2b posix: use getutf8char to handle OS X filename percent-escaping
Matt Mackall <mpm@selenic.com>
parents: 26248
diff changeset
   456
            while pos < l:
b8381832ce2b posix: use getutf8char to handle OS X filename percent-escaping
Matt Mackall <mpm@selenic.com>
parents: 26248
diff changeset
   457
                try:
b8381832ce2b posix: use getutf8char to handle OS X filename percent-escaping
Matt Mackall <mpm@selenic.com>
parents: 26248
diff changeset
   458
                    c = encoding.getutf8char(path, pos)
b8381832ce2b posix: use getutf8char to handle OS X filename percent-escaping
Matt Mackall <mpm@selenic.com>
parents: 26248
diff changeset
   459
                    pos += len(c)
b8381832ce2b posix: use getutf8char to handle OS X filename percent-escaping
Matt Mackall <mpm@selenic.com>
parents: 26248
diff changeset
   460
                except ValueError:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   461
                    c = b'%%%02X' % ord(path[pos : pos + 1])
26876
b8381832ce2b posix: use getutf8char to handle OS X filename percent-escaping
Matt Mackall <mpm@selenic.com>
parents: 26248
diff changeset
   462
                    pos += 1
b8381832ce2b posix: use getutf8char to handle OS X filename percent-escaping
Matt Mackall <mpm@selenic.com>
parents: 26248
diff changeset
   463
                s += c
19131
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   464
15551
1fa41d1f1351 posix: add extended support for OS X path folding
Matt Mackall <mpm@selenic.com>
parents: 15499
diff changeset
   465
            u = s.decode('utf-8')
1fa41d1f1351 posix: add extended support for OS X path folding
Matt Mackall <mpm@selenic.com>
parents: 15499
diff changeset
   466
1fa41d1f1351 posix: add extended support for OS X path folding
Matt Mackall <mpm@selenic.com>
parents: 15499
diff changeset
   467
        # Decompose then lowercase (HFS+ technote specifies lower)
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43477
diff changeset
   468
        enc = unicodedata.normalize('NFD', u).lower().encode('utf-8')
23597
7a5bcd471f2e darwin: omit ignorable codepoints when normcase()ing a file path
Augie Fackler <raf@durin42.com>
parents: 22946
diff changeset
   469
        # drop HFS+ ignored characters
7a5bcd471f2e darwin: omit ignorable codepoints when normcase()ing a file path
Augie Fackler <raf@durin42.com>
parents: 22946
diff changeset
   470
        return encoding.hfsignoreclean(enc)
15551
1fa41d1f1351 posix: add extended support for OS X path folding
Matt Mackall <mpm@selenic.com>
parents: 15499
diff changeset
   471
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   472
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   473
if pycompat.sysplatform == b'cygwin':
15711
c51c9dc13a58 cygwin: add cygwin specific normcase logic
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15672
diff changeset
   474
    # 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
   475
    # 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
   476
    # insensitive.
c51c9dc13a58 cygwin: add cygwin specific normcase logic
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15672
diff changeset
   477
c51c9dc13a58 cygwin: add cygwin specific normcase logic
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15672
diff changeset
   478
    # default mount points
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   479
    cygwinmountpoints = sorted(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   480
        [b"/usr/bin", b"/usr/lib", b"/cygdrive",], reverse=True
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   481
    )
15711
c51c9dc13a58 cygwin: add cygwin specific normcase logic
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15672
diff changeset
   482
c51c9dc13a58 cygwin: add cygwin specific normcase logic
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15672
diff changeset
   483
    # 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
   484
    def normcase(path):
c51c9dc13a58 cygwin: add cygwin specific normcase logic
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15672
diff changeset
   485
        pathlen = len(path)
30614
cfe66dcf45c0 py3: replace os.sep with pycompat.ossep (part 2 of 4)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30612
diff changeset
   486
        if (pathlen == 0) or (path[0] != pycompat.ossep):
15711
c51c9dc13a58 cygwin: add cygwin specific normcase logic
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15672
diff changeset
   487
            # treat as relative
17203
0cb55b5c19a3 util, posix: eliminate encodinglower and encodingupper
Adrian Buehlmann <adrian@cadifra.com>
parents: 16726
diff changeset
   488
            return encoding.upper(path)
15711
c51c9dc13a58 cygwin: add cygwin specific normcase logic
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15672
diff changeset
   489
c51c9dc13a58 cygwin: add cygwin specific normcase logic
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15672
diff changeset
   490
        # to preserve case of mountpoint part
c51c9dc13a58 cygwin: add cygwin specific normcase logic
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15672
diff changeset
   491
        for mp in cygwinmountpoints:
c51c9dc13a58 cygwin: add cygwin specific normcase logic
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15672
diff changeset
   492
            if not path.startswith(mp):
c51c9dc13a58 cygwin: add cygwin specific normcase logic
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15672
diff changeset
   493
                continue
c51c9dc13a58 cygwin: add cygwin specific normcase logic
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15672
diff changeset
   494
c51c9dc13a58 cygwin: add cygwin specific normcase logic
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15672
diff changeset
   495
            mplen = len(mp)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   496
            if mplen == pathlen:  # mount point itself
15711
c51c9dc13a58 cygwin: add cygwin specific normcase logic
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15672
diff changeset
   497
                return mp
30614
cfe66dcf45c0 py3: replace os.sep with pycompat.ossep (part 2 of 4)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30612
diff changeset
   498
            if path[mplen] == pycompat.ossep:
17203
0cb55b5c19a3 util, posix: eliminate encodinglower and encodingupper
Adrian Buehlmann <adrian@cadifra.com>
parents: 16726
diff changeset
   499
                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
   500
17203
0cb55b5c19a3 util, posix: eliminate encodinglower and encodingupper
Adrian Buehlmann <adrian@cadifra.com>
parents: 16726
diff changeset
   501
        return encoding.upper(path)
15711
c51c9dc13a58 cygwin: add cygwin specific normcase logic
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15672
diff changeset
   502
24596
75ea27f1711d cygwin: define normcase spec and fallback
Siddharth Agarwal <sid0@fb.com>
parents: 24595
diff changeset
   503
    normcasespec = encoding.normcasespecs.other
75ea27f1711d cygwin: define normcase spec and fallback
Siddharth Agarwal <sid0@fb.com>
parents: 24595
diff changeset
   504
    normcasefallback = normcase
75ea27f1711d cygwin: define normcase spec and fallback
Siddharth Agarwal <sid0@fb.com>
parents: 24595
diff changeset
   505
16240
95e45abe7e8e posix: ignore execution bit in cygwin (issue3301)
A. S. Budden <abudden@gmail.com>
parents: 15791
diff changeset
   506
    # 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
   507
    # 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
   508
    # 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
   509
    # 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
   510
    def checkexec(path):
95e45abe7e8e posix: ignore execution bit in cygwin (issue3301)
A. S. Budden <abudden@gmail.com>
parents: 15791
diff changeset
   511
        return False
95e45abe7e8e posix: ignore execution bit in cygwin (issue3301)
A. S. Budden <abudden@gmail.com>
parents: 15791
diff changeset
   512
16241
60cc3a0d2249 posix: disable cygwin's symlink emulation
Matt Mackall <mpm@selenic.com>
parents: 16240
diff changeset
   513
    # 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
   514
    # 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
   515
    # 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
   516
    def checklink(path):
60cc3a0d2249 posix: disable cygwin's symlink emulation
Matt Mackall <mpm@selenic.com>
parents: 16240
diff changeset
   517
        return False
60cc3a0d2249 posix: disable cygwin's symlink emulation
Matt Mackall <mpm@selenic.com>
parents: 16240
diff changeset
   518
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   519
23683
5edb387158a1 posix: quote the specified string only when it may have to be quoted
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23597
diff changeset
   520
_needsshellquote = None
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   521
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   522
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   523
def shellquote(s):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   524
    if pycompat.sysplatform == b'OpenVMS':
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   525
        return b'"%s"' % s
23683
5edb387158a1 posix: quote the specified string only when it may have to be quoted
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23597
diff changeset
   526
    global _needsshellquote
5edb387158a1 posix: quote the specified string only when it may have to be quoted
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23597
diff changeset
   527
    if _needsshellquote is None:
31491
492c64afc54c py3: make the regular expression bytes to prevent TypeError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30697
diff changeset
   528
        _needsshellquote = re.compile(br'[^a-zA-Z0-9._/+-]').search
24108
d65ecb814fc0 shellquote: fix missing quotes for empty string
Yuya Nishihara <yuya@tcha.org>
parents: 23683
diff changeset
   529
    if s and not _needsshellquote(s):
23683
5edb387158a1 posix: quote the specified string only when it may have to be quoted
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23597
diff changeset
   530
        # "s" shouldn't have to be quoted
5edb387158a1 posix: quote the specified string only when it may have to be quoted
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23597
diff changeset
   531
        return s
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   532
    else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   533
        return b"'%s'" % s.replace(b"'", b"'\\''")
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   534
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   535
36415
0cb09c322647 util: factor out shellsplit() function
Yuya Nishihara <yuya@tcha.org>
parents: 36303
diff changeset
   536
def shellsplit(s):
0cb09c322647 util: factor out shellsplit() function
Yuya Nishihara <yuya@tcha.org>
parents: 36303
diff changeset
   537
    """Parse a command string in POSIX shell way (best-effort)"""
0cb09c322647 util: factor out shellsplit() function
Yuya Nishihara <yuya@tcha.org>
parents: 36303
diff changeset
   538
    return pycompat.shlexsplit(s, posix=True)
0cb09c322647 util: factor out shellsplit() function
Yuya Nishihara <yuya@tcha.org>
parents: 36303
diff changeset
   539
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   540
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   541
def testpid(pid):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   542
    '''return False if pid dead, True if running or not sure'''
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   543
    if pycompat.sysplatform == b'OpenVMS':
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   544
        return True
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   545
    try:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   546
        os.kill(pid, 0)
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   547
        return True
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25658
diff changeset
   548
    except OSError as inst:
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   549
        return inst.errno != errno.ESRCH
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   550
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   551
8657
3fa92c618624 posix: do not use fstat in isowner
Martin Geisler <mg@lazybytes.net>
parents: 8614
diff changeset
   552
def isowner(st):
3fa92c618624 posix: do not use fstat in isowner
Martin Geisler <mg@lazybytes.net>
parents: 8614
diff changeset
   553
    """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
   554
    return st.st_uid == os.getuid()
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   555
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   556
14271
4030630fb59c rename util.find_exe to findexe
Adrian Buehlmann <adrian@cadifra.com>
parents: 14237
diff changeset
   557
def findexe(command):
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   558
    '''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
   559
    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
   560
    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
   561
    If command isn't found None is returned.'''
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   562
    if pycompat.sysplatform == b'OpenVMS':
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   563
        return command
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   564
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   565
    def findexisting(executable):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   566
        b'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
   567
        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
   568
            return executable
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   569
        return None
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   570
30614
cfe66dcf45c0 py3: replace os.sep with pycompat.ossep (part 2 of 4)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30612
diff changeset
   571
    if pycompat.ossep in command:
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   572
        return findexisting(command)
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   573
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   574
    if pycompat.sysplatform == b'plan9':
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   575
        return findexisting(os.path.join(b'/bin', command))
16383
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents: 16241
diff changeset
   576
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   577
    for path in encoding.environ.get(b'PATH', b'').split(pycompat.ospathsep):
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   578
        executable = findexisting(os.path.join(path, command))
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   579
        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
   580
            return executable
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   581
    return None
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   582
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   583
14237
4d684d8210a1 rename util.set_signal_handler to setsignalhandler
Adrian Buehlmann <adrian@cadifra.com>
parents: 14235
diff changeset
   584
def setsignalhandler():
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   585
    pass
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   586
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   587
32291
bd872f64a8ba cleanup: use set literals
Martin von Zweigbergk <martinvonz@google.com>
parents: 32129
diff changeset
   588
_wantedkinds = {stat.S_IFREG, stat.S_IFLNK}
18017
74912fe3d718 dirstate: move file type filtering to its source
Bryan O'Sullivan <bryano@fb.com>
parents: 17560
diff changeset
   589
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   590
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   591
def statfiles(files):
18017
74912fe3d718 dirstate: move file type filtering to its source
Bryan O'Sullivan <bryano@fb.com>
parents: 17560
diff changeset
   592
    '''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
   593
    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
   594
    lstat = os.lstat
18017
74912fe3d718 dirstate: move file type filtering to its source
Bryan O'Sullivan <bryano@fb.com>
parents: 17560
diff changeset
   595
    getkind = stat.S_IFMT
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   596
    for nf in files:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   597
        try:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   598
            st = lstat(nf)
18017
74912fe3d718 dirstate: move file type filtering to its source
Bryan O'Sullivan <bryano@fb.com>
parents: 17560
diff changeset
   599
            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
   600
                st = None
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25658
diff changeset
   601
        except OSError as err:
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   602
            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
   603
                raise
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   604
            st = None
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   605
        yield st
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   606
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   607
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   608
def getuser():
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   609
    '''return name of current user'''
32129
f0ea0f642627 py3: make posix.getuser return a bytes
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31539
diff changeset
   610
    return pycompat.fsencode(getpass.getuser())
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   611
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   612
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   613
def username(uid=None):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   614
    """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
   615
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   616
    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
   617
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   618
    if uid is None:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   619
        uid = os.getuid()
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   620
    try:
38252
a4aa77b84efd py3: make sure util.username() always returns bytes
Pulkit Goyal <7895pulkit@gmail.com>
parents: 38166
diff changeset
   621
        return pycompat.fsencode(pwd.getpwuid(uid)[0])
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   622
    except KeyError:
38252
a4aa77b84efd py3: make sure util.username() always returns bytes
Pulkit Goyal <7895pulkit@gmail.com>
parents: 38166
diff changeset
   623
        return b'%d' % uid
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   624
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   625
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   626
def groupname(gid=None):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   627
    """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
   628
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   629
    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
   630
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   631
    if gid is None:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   632
        gid = os.getgid()
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   633
    try:
41827
faa04f45b5fe py3: make sure return value of posix.groupname() is bytes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41523
diff changeset
   634
        return pycompat.fsencode(grp.getgrgid(gid)[0])
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   635
    except KeyError:
41827
faa04f45b5fe py3: make sure return value of posix.groupname() is bytes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41523
diff changeset
   636
        return pycompat.bytestr(gid)
10237
2f7a38f336f4 serve: add and use portable spawnvp replacement
Patrick Mezard <pmezard@gmail.com>
parents: 10218
diff changeset
   637
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   638
11138
99eee847beaa acl: grp module is not available on windows
Patrick Mezard <pmezard@gmail.com>
parents: 11011
diff changeset
   639
def groupmembers(name):
99eee847beaa acl: grp module is not available on windows
Patrick Mezard <pmezard@gmail.com>
parents: 11011
diff changeset
   640
    """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
   641
    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
   642
    """
41523
3ef8bec91465 py3: do a fsdecode(), fsencode() dance in posix.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41504
diff changeset
   643
    name = pycompat.fsdecode(name)
3ef8bec91465 py3: do a fsdecode(), fsencode() dance in posix.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41504
diff changeset
   644
    return pycompat.rapply(pycompat.fsencode, list(grp.getgrnam(name).gr_mem))
11138
99eee847beaa acl: grp module is not available on windows
Patrick Mezard <pmezard@gmail.com>
parents: 11011
diff changeset
   645
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   646
10237
2f7a38f336f4 serve: add and use portable spawnvp replacement
Patrick Mezard <pmezard@gmail.com>
parents: 10218
diff changeset
   647
def spawndetached(args):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   648
    return os.spawnvp(os.P_NOWAIT | getattr(os, 'P_DETACH', 0), args[0], args)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   649
10237
2f7a38f336f4 serve: add and use portable spawnvp replacement
Patrick Mezard <pmezard@gmail.com>
parents: 10218
diff changeset
   650
10239
8e4be44a676f Find right hg command for detached process
Patrick Mezard <pmezard@gmail.com>
parents: 10237
diff changeset
   651
def gethgcmd():
8e4be44a676f Find right hg command for detached process
Patrick Mezard <pmezard@gmail.com>
parents: 10237
diff changeset
   652
    return sys.argv[:1]
11010
18e81d42ee5c util: fix default termwidth() under Windows
Patrick Mezard <pmezard@gmail.com>
parents: 10264
diff changeset
   653
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   654
14908
e2b5605501df util: move "default" makedir to posix.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 14273
diff changeset
   655
def makedir(path, notindexed):
e2b5605501df util: move "default" makedir to posix.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 14273
diff changeset
   656
    os.mkdir(path)
14909
c627fe32c923 util: move "default" unlinkpath to posix.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 14908
diff changeset
   657
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   658
14910
570ea0259b0a util: move "default" lookupreg to posix.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 14909
diff changeset
   659
def lookupreg(key, name=None, scope=None):
570ea0259b0a util: move "default" lookupreg to posix.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 14909
diff changeset
   660
    return None
14911
5b39503157fd util: move "default" hidewindow to posix.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 14910
diff changeset
   661
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   662
14911
5b39503157fd util: move "default" hidewindow to posix.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 14910
diff changeset
   663
def hidewindow():
5b39503157fd util: move "default" hidewindow to posix.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 14910
diff changeset
   664
    """Hide current shell window.
5b39503157fd util: move "default" hidewindow to posix.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 14910
diff changeset
   665
5b39503157fd util: move "default" hidewindow to posix.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 14910
diff changeset
   666
    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
   667
    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
   668
    """
5b39503157fd util: move "default" hidewindow to posix.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 14910
diff changeset
   669
    pass
14926
4e7e63fc685a util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents: 14911
diff changeset
   670
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   671
14927
2aa3e07b2f07 posix, windows: introduce cachestat
Idan Kamara <idankk86@gmail.com>
parents: 14926
diff changeset
   672
class cachestat(object):
2aa3e07b2f07 posix, windows: introduce cachestat
Idan Kamara <idankk86@gmail.com>
parents: 14926
diff changeset
   673
    def __init__(self, path):
2aa3e07b2f07 posix, windows: introduce cachestat
Idan Kamara <idankk86@gmail.com>
parents: 14926
diff changeset
   674
        self.stat = os.stat(path)
2aa3e07b2f07 posix, windows: introduce cachestat
Idan Kamara <idankk86@gmail.com>
parents: 14926
diff changeset
   675
2aa3e07b2f07 posix, windows: introduce cachestat
Idan Kamara <idankk86@gmail.com>
parents: 14926
diff changeset
   676
    def cacheable(self):
2aa3e07b2f07 posix, windows: introduce cachestat
Idan Kamara <idankk86@gmail.com>
parents: 14926
diff changeset
   677
        return bool(self.stat.st_ino)
2aa3e07b2f07 posix, windows: introduce cachestat
Idan Kamara <idankk86@gmail.com>
parents: 14926
diff changeset
   678
15791
a814f8fcc65a Use explicit integer division
Martin Geisler <mg@aragost.com>
parents: 15711
diff changeset
   679
    __hash__ = object.__hash__
a814f8fcc65a Use explicit integer division
Martin Geisler <mg@aragost.com>
parents: 15711
diff changeset
   680
14927
2aa3e07b2f07 posix, windows: introduce cachestat
Idan Kamara <idankk86@gmail.com>
parents: 14926
diff changeset
   681
    def __eq__(self, other):
2aa3e07b2f07 posix, windows: introduce cachestat
Idan Kamara <idankk86@gmail.com>
parents: 14926
diff changeset
   682
        try:
18442
ecba9b0e7672 posix: don't compare atime when determining if a file has changed
Siddharth Agarwal <sid0@fb.com>
parents: 18288
diff changeset
   683
            # 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
   684
            # 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
   685
            # 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
   686
            # 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
   687
            # changes.
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   688
            return (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   689
                self.stat.st_mode == other.stat.st_mode
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   690
                and self.stat.st_ino == other.stat.st_ino
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   691
                and self.stat.st_dev == other.stat.st_dev
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   692
                and self.stat.st_nlink == other.stat.st_nlink
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   693
                and self.stat.st_uid == other.stat.st_uid
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   694
                and self.stat.st_gid == other.stat.st_gid
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   695
                and self.stat.st_size == other.stat.st_size
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   696
                and self.stat[stat.ST_MTIME] == other.stat[stat.ST_MTIME]
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   697
                and self.stat[stat.ST_CTIME] == other.stat[stat.ST_CTIME]
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   698
            )
14927
2aa3e07b2f07 posix, windows: introduce cachestat
Idan Kamara <idankk86@gmail.com>
parents: 14926
diff changeset
   699
        except AttributeError:
2aa3e07b2f07 posix, windows: introduce cachestat
Idan Kamara <idankk86@gmail.com>
parents: 14926
diff changeset
   700
            return False
2aa3e07b2f07 posix, windows: introduce cachestat
Idan Kamara <idankk86@gmail.com>
parents: 14926
diff changeset
   701
2aa3e07b2f07 posix, windows: introduce cachestat
Idan Kamara <idankk86@gmail.com>
parents: 14926
diff changeset
   702
    def __ne__(self, other):
2aa3e07b2f07 posix, windows: introduce cachestat
Idan Kamara <idankk86@gmail.com>
parents: 14926
diff changeset
   703
        return not self == other
2aa3e07b2f07 posix, windows: introduce cachestat
Idan Kamara <idankk86@gmail.com>
parents: 14926
diff changeset
   704
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   705
18868
cafa447a7d3b util: add functions to check symlink/exec bits
Bryan O'Sullivan <bryano@fb.com>
parents: 18501
diff changeset
   706
def statislink(st):
cafa447a7d3b util: add functions to check symlink/exec bits
Bryan O'Sullivan <bryano@fb.com>
parents: 18501
diff changeset
   707
    '''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
   708
    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
   709
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   710
18868
cafa447a7d3b util: add functions to check symlink/exec bits
Bryan O'Sullivan <bryano@fb.com>
parents: 18501
diff changeset
   711
def statisexec(st):
cafa447a7d3b util: add functions to check symlink/exec bits
Bryan O'Sullivan <bryano@fb.com>
parents: 18501
diff changeset
   712
    '''check whether a stat result is an executable file'''
25658
e93036747902 global: mass rewrite to use modern octal syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25420
diff changeset
   713
    return st and (st.st_mode & 0o100 != 0)
22245
234e4c24b980 platform: implement readpipe()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 20202
diff changeset
   714
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   715
25420
c2ec81891502 util: add a simple poll utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24692
diff changeset
   716
def poll(fds):
c2ec81891502 util: add a simple poll utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24692
diff changeset
   717
    """block until something happens on any file descriptor
c2ec81891502 util: add a simple poll utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24692
diff changeset
   718
c2ec81891502 util: add a simple poll utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24692
diff changeset
   719
    This is a generic helper that will check for any activity
c2ec81891502 util: add a simple poll utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24692
diff changeset
   720
    (read, write.  exception) and return the list of touched files.
c2ec81891502 util: add a simple poll utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24692
diff changeset
   721
c2ec81891502 util: add a simple poll utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24692
diff changeset
   722
    In unsupported cases, it will raise a NotImplementedError"""
c2ec81891502 util: add a simple poll utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24692
diff changeset
   723
    try:
30654
5f33116cd787 posix: make poll() restart on interruption by signal (issue5452)
Yuya Nishihara <yuya@tcha.org>
parents: 29530
diff changeset
   724
        while True:
5f33116cd787 posix: make poll() restart on interruption by signal (issue5452)
Yuya Nishihara <yuya@tcha.org>
parents: 29530
diff changeset
   725
            try:
5f33116cd787 posix: make poll() restart on interruption by signal (issue5452)
Yuya Nishihara <yuya@tcha.org>
parents: 29530
diff changeset
   726
                res = select.select(fds, fds, fds)
5f33116cd787 posix: make poll() restart on interruption by signal (issue5452)
Yuya Nishihara <yuya@tcha.org>
parents: 29530
diff changeset
   727
                break
5f33116cd787 posix: make poll() restart on interruption by signal (issue5452)
Yuya Nishihara <yuya@tcha.org>
parents: 29530
diff changeset
   728
            except select.error as inst:
5f33116cd787 posix: make poll() restart on interruption by signal (issue5452)
Yuya Nishihara <yuya@tcha.org>
parents: 29530
diff changeset
   729
                if inst.args[0] == errno.EINTR:
5f33116cd787 posix: make poll() restart on interruption by signal (issue5452)
Yuya Nishihara <yuya@tcha.org>
parents: 29530
diff changeset
   730
                    continue
5f33116cd787 posix: make poll() restart on interruption by signal (issue5452)
Yuya Nishihara <yuya@tcha.org>
parents: 29530
diff changeset
   731
                raise
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   732
    except ValueError:  # out of range file descriptor
25420
c2ec81891502 util: add a simple poll utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24692
diff changeset
   733
        raise NotImplementedError()
c2ec81891502 util: add a simple poll utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24692
diff changeset
   734
    return sorted(list(set(sum(res, []))))
c2ec81891502 util: add a simple poll utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24692
diff changeset
   735
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   736
22245
234e4c24b980 platform: implement readpipe()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 20202
diff changeset
   737
def readpipe(pipe):
234e4c24b980 platform: implement readpipe()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 20202
diff changeset
   738
    """Read all available data from a pipe."""
22246
331cbf088c4c posix: implement readpipe using non-blocking I/O (issue4336)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22245
diff changeset
   739
    # We can't fstat() a pipe because Linux will always report 0.
331cbf088c4c posix: implement readpipe using non-blocking I/O (issue4336)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22245
diff changeset
   740
    # So, we set the pipe to non-blocking mode and read everything
331cbf088c4c posix: implement readpipe using non-blocking I/O (issue4336)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22245
diff changeset
   741
    # that's available.
331cbf088c4c posix: implement readpipe using non-blocking I/O (issue4336)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22245
diff changeset
   742
    flags = fcntl.fcntl(pipe, fcntl.F_GETFL)
331cbf088c4c posix: implement readpipe using non-blocking I/O (issue4336)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22245
diff changeset
   743
    flags |= os.O_NONBLOCK
331cbf088c4c posix: implement readpipe using non-blocking I/O (issue4336)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22245
diff changeset
   744
    oldflags = fcntl.fcntl(pipe, fcntl.F_SETFL, flags)
22245
234e4c24b980 platform: implement readpipe()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 20202
diff changeset
   745
22246
331cbf088c4c posix: implement readpipe using non-blocking I/O (issue4336)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22245
diff changeset
   746
    try:
331cbf088c4c posix: implement readpipe using non-blocking I/O (issue4336)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22245
diff changeset
   747
        chunks = []
331cbf088c4c posix: implement readpipe using non-blocking I/O (issue4336)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22245
diff changeset
   748
        while True:
331cbf088c4c posix: implement readpipe using non-blocking I/O (issue4336)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22245
diff changeset
   749
            try:
331cbf088c4c posix: implement readpipe using non-blocking I/O (issue4336)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22245
diff changeset
   750
                s = pipe.read()
331cbf088c4c posix: implement readpipe using non-blocking I/O (issue4336)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22245
diff changeset
   751
                if not s:
331cbf088c4c posix: implement readpipe using non-blocking I/O (issue4336)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22245
diff changeset
   752
                    break
331cbf088c4c posix: implement readpipe using non-blocking I/O (issue4336)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22245
diff changeset
   753
                chunks.append(s)
331cbf088c4c posix: implement readpipe using non-blocking I/O (issue4336)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22245
diff changeset
   754
            except IOError:
331cbf088c4c posix: implement readpipe using non-blocking I/O (issue4336)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22245
diff changeset
   755
                break
331cbf088c4c posix: implement readpipe using non-blocking I/O (issue4336)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22245
diff changeset
   756
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   757
        return b''.join(chunks)
22246
331cbf088c4c posix: implement readpipe using non-blocking I/O (issue4336)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22245
diff changeset
   758
    finally:
331cbf088c4c posix: implement readpipe using non-blocking I/O (issue4336)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22245
diff changeset
   759
        fcntl.fcntl(pipe, fcntl.F_SETFL, oldflags)
29530
3239e2fdd2e2 chgserver: extract utility to bind unix domain socket to long path
Yuya Nishihara <yuya@tcha.org>
parents: 27380
diff changeset
   760
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   761
29530
3239e2fdd2e2 chgserver: extract utility to bind unix domain socket to long path
Yuya Nishihara <yuya@tcha.org>
parents: 27380
diff changeset
   762
def bindunixsocket(sock, path):
3239e2fdd2e2 chgserver: extract utility to bind unix domain socket to long path
Yuya Nishihara <yuya@tcha.org>
parents: 27380
diff changeset
   763
    """Bind the UNIX domain socket to the specified path"""
3239e2fdd2e2 chgserver: extract utility to bind unix domain socket to long path
Yuya Nishihara <yuya@tcha.org>
parents: 27380
diff changeset
   764
    # use relative path instead of full path at bind() if possible, since
3239e2fdd2e2 chgserver: extract utility to bind unix domain socket to long path
Yuya Nishihara <yuya@tcha.org>
parents: 27380
diff changeset
   765
    # AF_UNIX path has very small length limit (107 chars) on common
3239e2fdd2e2 chgserver: extract utility to bind unix domain socket to long path
Yuya Nishihara <yuya@tcha.org>
parents: 27380
diff changeset
   766
    # platforms (see sys/un.h)
3239e2fdd2e2 chgserver: extract utility to bind unix domain socket to long path
Yuya Nishihara <yuya@tcha.org>
parents: 27380
diff changeset
   767
    dirname, basename = os.path.split(path)
3239e2fdd2e2 chgserver: extract utility to bind unix domain socket to long path
Yuya Nishihara <yuya@tcha.org>
parents: 27380
diff changeset
   768
    bakwdfd = None
3239e2fdd2e2 chgserver: extract utility to bind unix domain socket to long path
Yuya Nishihara <yuya@tcha.org>
parents: 27380
diff changeset
   769
    if dirname:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   770
        bakwdfd = os.open(b'.', os.O_DIRECTORY)
29530
3239e2fdd2e2 chgserver: extract utility to bind unix domain socket to long path
Yuya Nishihara <yuya@tcha.org>
parents: 27380
diff changeset
   771
        os.chdir(dirname)
3239e2fdd2e2 chgserver: extract utility to bind unix domain socket to long path
Yuya Nishihara <yuya@tcha.org>
parents: 27380
diff changeset
   772
    sock.bind(basename)
3239e2fdd2e2 chgserver: extract utility to bind unix domain socket to long path
Yuya Nishihara <yuya@tcha.org>
parents: 27380
diff changeset
   773
    if bakwdfd:
3239e2fdd2e2 chgserver: extract utility to bind unix domain socket to long path
Yuya Nishihara <yuya@tcha.org>
parents: 27380
diff changeset
   774
        os.fchdir(bakwdfd)
3239e2fdd2e2 chgserver: extract utility to bind unix domain socket to long path
Yuya Nishihara <yuya@tcha.org>
parents: 27380
diff changeset
   775
        os.close(bakwdfd)