mercurial/posix.py
author Matt Harbison <matt_harbison@yahoo.com>
Fri, 16 Dec 2022 00:54:39 -0500
changeset 49812 58dff81ffba1
parent 49811 0a91aba258e0
child 49815 464fe8b8f474
permissions -rw-r--r--
typing: add type hints to the common posix/windows platform functions These are done in sync because some platforms have empty implementations, and it isn't obvious what the types should be without examining the other. We want the types aligned, so @overload definitions that differ aren't generated. The only differences here are the few methods that unconditionally raise an error are marked as `NoReturn`, which doesn't seem to bother pytype. A couple of the posix module functions needed to be updated with a modern ternary operator, because pytype seems to want to use the type of the second object in the old `return x and y` style.
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
#
46819
d4ba4d51f85f contributor: change mentions of mpm to olivia
Raphaël Gomès <rgomes@octobus.net>
parents: 46680
diff changeset
     3
#  Copyright 2005-2009 Olivia Mackall <olivia@selenic.com> and others
8226
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
224a33452ed4 posix: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
     9
import errno
224a33452ed4 posix: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    10
import fcntl
224a33452ed4 posix: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    11
import getpass
224a33452ed4 posix: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    12
import grp
224a33452ed4 posix: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    13
import os
224a33452ed4 posix: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    14
import pwd
224a33452ed4 posix: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    15
import re
25420
c2ec81891502 util: add a simple poll utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24692
diff changeset
    16
import select
25967
224a33452ed4 posix: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    17
import stat
224a33452ed4 posix: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    18
import sys
224a33452ed4 posix: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    19
import tempfile
224a33452ed4 posix: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    20
import unicodedata
224a33452ed4 posix: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    21
49811
0a91aba258e0 typing: add type hints to the posix platform module matching win32.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49810
diff changeset
    22
from typing import (
49812
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49811
diff changeset
    23
    Iterable,
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49811
diff changeset
    24
    Iterator,
49811
0a91aba258e0 typing: add type hints to the posix platform module matching win32.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49810
diff changeset
    25
    List,
0a91aba258e0 typing: add type hints to the posix platform module matching win32.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49810
diff changeset
    26
    NoReturn,
0a91aba258e0 typing: add type hints to the posix platform module matching win32.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49810
diff changeset
    27
    Optional,
49812
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49811
diff changeset
    28
    Sequence,
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49811
diff changeset
    29
    Union,
49811
0a91aba258e0 typing: add type hints to the posix platform module matching win32.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49810
diff changeset
    30
)
0a91aba258e0 typing: add type hints to the posix platform module matching win32.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49810
diff changeset
    31
25967
224a33452ed4 posix: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    32
from .i18n import _
43089
c59eb1560c44 py3: manually import getattr where it is needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43085
diff changeset
    33
from .pycompat import (
c59eb1560c44 py3: manually import getattr where it is needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43085
diff changeset
    34
    getattr,
c59eb1560c44 py3: manually import getattr where it is needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43085
diff changeset
    35
    open,
c59eb1560c44 py3: manually import getattr where it is needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43085
diff changeset
    36
)
25967
224a33452ed4 posix: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    37
from . import (
224a33452ed4 posix: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    38
    encoding,
33651
739cc0f9cbb4 ssh: ban any username@host or host that starts with - (SEC)
Augie Fackler <augie@google.com>
parents: 32721
diff changeset
    39
    error,
35509
beede158ea8a util: move getfstype() to the platform modules
Matt Harbison <matt_harbison@yahoo.com>
parents: 34647
diff changeset
    40
    policy,
30612
d623cc6b3742 py3: replace os.pathsep with pycompat.ospathsep
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30555
diff changeset
    41
    pycompat,
25967
224a33452ed4 posix: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    42
)
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    43
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43477
diff changeset
    44
osutil = policy.importmod('osutil')
35509
beede158ea8a util: move getfstype() to the platform modules
Matt Harbison <matt_harbison@yahoo.com>
parents: 34647
diff changeset
    45
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    46
normpath = os.path.normpath
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    47
samestat = os.path.samestat
47622
bb917eea1605 windows: introduce a `util.abspath` to replace os.path.abspath
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47079
diff changeset
    48
abspath = os.path.abspath  # re-exports
bb917eea1605 windows: introduce a `util.abspath` to replace os.path.abspath
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47079
diff changeset
    49
27236
b0d90fef16b6 posix: work around "posix" systems without os.link available (issue4974)
Augie Fackler <augie@google.com>
parents: 26901
diff changeset
    50
try:
b0d90fef16b6 posix: work around "posix" systems without os.link available (issue4974)
Augie Fackler <augie@google.com>
parents: 26901
diff changeset
    51
    oslink = os.link
b0d90fef16b6 posix: work around "posix" systems without os.link available (issue4974)
Augie Fackler <augie@google.com>
parents: 26901
diff changeset
    52
except AttributeError:
b0d90fef16b6 posix: work around "posix" systems without os.link available (issue4974)
Augie Fackler <augie@google.com>
parents: 26901
diff changeset
    53
    # 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
    54
    # 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
    55
    # 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
    56
    # to copies.
49811
0a91aba258e0 typing: add type hints to the posix platform module matching win32.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49810
diff changeset
    57
    def oslink(src: bytes, dst: bytes) -> NoReturn:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
    58
        raise OSError(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    59
            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
    60
        )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
    61
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
    62
39904
5fe0b880200e py3: convert os.readlink() path to native strings on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 38252
diff changeset
    63
readlink = os.readlink
13280
6052bbc7aabd reintroduces util.unlink, for POSIX and Windows.
Adrian Buehlmann <adrian@cadifra.com>
parents: 13007
diff changeset
    64
unlink = os.unlink
9549
8b8920209317 util: move rename into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 9517
diff changeset
    65
rename = os.rename
24692
144883a8d0d4 util: add removedirs as platform depending function
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24596
diff changeset
    66
removedirs = os.removedirs
8614
573734e7e6d0 cmdutils: Take over glob expansion duties from util
Matt Mackall <mpm@selenic.com>
parents: 8312
diff changeset
    67
expandglobs = False
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    68
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    69
umask = os.umask(0)
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    70
os.umask(umask)
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    71
48885
a2c59b361e0f posix: delete Python 2 posixfile()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48875
diff changeset
    72
posixfile = open
42562
97ada9b8d51b posix: always seek to EOF when opening a file in append mode
Augie Fackler <augie@google.com>
parents: 41827
diff changeset
    73
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
    74
17560
9ee25d7b1aed util: implement a faster os.path.split for posix systems
Bryan O'Sullivan <bryano@fb.com>
parents: 17391
diff changeset
    75
def split(p):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45718
diff changeset
    76
    """Same as posixpath.split, but faster
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
    77
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
    78
    >>> import posixpath
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33659
diff changeset
    79
    >>> 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
    80
    ...           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
    81
    ...           b'file_alone',
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33659
diff changeset
    82
    ...           b'path/to/directory/',
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33659
diff changeset
    83
    ...           b'/multiple/path//separators',
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33659
diff changeset
    84
    ...           b'/file_at_root',
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33659
diff changeset
    85
    ...           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
    86
    ...           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
    87
    ...     assert split(f) == posixpath.split(f), f
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45718
diff changeset
    88
    """
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    89
    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
    90
    if len(ht) == 1:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    91
        return b'', p
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    92
    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
    93
    if nh:
9ee25d7b1aed util: implement a faster os.path.split for posix systems
Bryan O'Sullivan <bryano@fb.com>
parents: 17391
diff changeset
    94
        return nh, ht[1]
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    95
    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
    96
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
    97
49812
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49811
diff changeset
    98
def openhardlinks() -> bool:
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    99
    '''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
   100
    return True
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   101
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   102
49811
0a91aba258e0 typing: add type hints to the posix platform module matching win32.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49810
diff changeset
   103
def nlinks(name: bytes) -> int:
13375
f1fa8f481c7c port win32.py to using the Python ctypes library
Adrian Buehlmann <adrian@cadifra.com>
parents: 13280
diff changeset
   104
    '''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
   105
    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
   106
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   107
49812
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49811
diff changeset
   108
def parsepatchoutput(output_line: bytes) -> bytes:
8761
0289f384e1e5 Generally replace "file name" with "filename" in help and comments.
timeless <timeless@gmail.com>
parents: 8657
diff changeset
   109
    """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
   110
    pf = output_line[14:]
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   111
    if pycompat.sysplatform == b'OpenVMS':
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   112
        if pf[0] == b'`':
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   113
            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
   114
    else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   115
        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
   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
    return pf
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   118
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   119
49812
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49811
diff changeset
   120
def sshargs(
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49811
diff changeset
   121
    sshcmd: bytes, host: bytes, user: Optional[bytes], port: Optional[bytes]
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49811
diff changeset
   122
) -> bytes:
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   123
    '''Build argument list for ssh'''
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   124
    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
   125
    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
   126
        raise error.Abort(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   127
            _(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
   128
        )
33659
8cb9e921ef8c ssh: quote parameters using shellquote (SEC)
Jun Wu <quark@fb.com>
parents: 33651
diff changeset
   129
    args = shellquote(args)
8cb9e921ef8c ssh: quote parameters using shellquote (SEC)
Jun Wu <quark@fb.com>
parents: 33651
diff changeset
   130
    if port:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   131
        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
   132
    return args
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   133
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   134
49812
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49811
diff changeset
   135
def isexec(f: bytes) -> bool:
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   136
    """check whether a file is executable"""
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   137
    return os.lstat(f).st_mode & 0o100 != 0
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   138
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   139
49812
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49811
diff changeset
   140
def setflags(f: bytes, l: bool, x: bool) -> None:
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
   141
    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
   142
    s = st.st_mode
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   143
    if l:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   144
        if not stat.S_ISLNK(s):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   145
            # switch file to link
45717
755214a84b9d posix: use context managers in a couple of places
Matt Harbison <matt_harbison@yahoo.com>
parents: 44867
diff changeset
   146
            with open(f, b'rb') as fp:
755214a84b9d posix: use context managers in a couple of places
Matt Harbison <matt_harbison@yahoo.com>
parents: 44867
diff changeset
   147
                data = fp.read()
31537
c6cbe5720353 posix: use local reference to unlink
Ryan McElroy <rmcelroy@fb.com>
parents: 31506
diff changeset
   148
            unlink(f)
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   149
            try:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   150
                os.symlink(data, f)
14004
97ed99d1f419 eliminate various naked except clauses
Idan Kamara <idankk86@gmail.com>
parents: 13986
diff changeset
   151
            except OSError:
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   152
                # failed to make a link, rewrite file
45717
755214a84b9d posix: use context managers in a couple of places
Matt Harbison <matt_harbison@yahoo.com>
parents: 44867
diff changeset
   153
                with open(f, b"wb") as fp:
755214a84b9d posix: use context managers in a couple of places
Matt Harbison <matt_harbison@yahoo.com>
parents: 44867
diff changeset
   154
                    fp.write(data)
755214a84b9d posix: use context managers in a couple of places
Matt Harbison <matt_harbison@yahoo.com>
parents: 44867
diff changeset
   155
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   156
        # no chmod needed at this point
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   157
        return
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   158
    if stat.S_ISLNK(s):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   159
        # switch link to file
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   160
        data = os.readlink(f)
31537
c6cbe5720353 posix: use local reference to unlink
Ryan McElroy <rmcelroy@fb.com>
parents: 31506
diff changeset
   161
        unlink(f)
45717
755214a84b9d posix: use context managers in a couple of places
Matt Harbison <matt_harbison@yahoo.com>
parents: 44867
diff changeset
   162
        with open(f, b"wb") as fp:
755214a84b9d posix: use context managers in a couple of places
Matt Harbison <matt_harbison@yahoo.com>
parents: 44867
diff changeset
   163
            fp.write(data)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   164
        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
   165
25658
e93036747902 global: mass rewrite to use modern octal syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25420
diff changeset
   166
    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
   167
    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
   168
        # 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
   169
        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
   170
            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
   171
        unlink(f)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   172
        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
   173
            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
   174
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   175
    if x and not sx:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   176
        # 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
   177
        # and obey umask.
25658
e93036747902 global: mass rewrite to use modern octal syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25420
diff changeset
   178
        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
   179
    elif not x and sx:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   180
        # 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
   181
        os.chmod(f, s & 0o666)
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   182
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   183
49812
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49811
diff changeset
   184
def copymode(
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49811
diff changeset
   185
    src: bytes,
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49811
diff changeset
   186
    dst: bytes,
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49811
diff changeset
   187
    mode: Optional[bytes] = None,
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49811
diff changeset
   188
    enforcewritable: bool = False,
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49811
diff changeset
   189
) -> None:
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45718
diff changeset
   190
    """Copy the file mode from the file at path src to dst.
15011
5e44e4b3a0a3 util: move copymode into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 14927
diff changeset
   191
    If src doesn't exist, we're using mode instead. If mode is None, we're
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45718
diff changeset
   192
    using umask."""
15011
5e44e4b3a0a3 util: move copymode into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 14927
diff changeset
   193
    try:
25658
e93036747902 global: mass rewrite to use modern octal syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25420
diff changeset
   194
        st_mode = os.lstat(src).st_mode & 0o777
49306
2e726c934fcd py3: catch FileNotFoundError instead of checking errno == ENOENT
Manuel Jacob <me@manueljacob.de>
parents: 49305
diff changeset
   195
    except FileNotFoundError:
15011
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
49812
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49811
diff changeset
   209
def checkexec(path: bytes) -> bool:
13879
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
49306
2e726c934fcd py3: catch FileNotFoundError instead of checking errno == ENOENT
Manuel Jacob <me@manueljacob.de>
parents: 49305
diff changeset
   244
            except FileNotFoundError:
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
   245
                # checkisexec does not exist - fall through ...
49306
2e726c934fcd py3: catch FileNotFoundError instead of checking errno == ENOENT
Manuel Jacob <me@manueljacob.de>
parents: 49305
diff changeset
   246
                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
   247
            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
   248
                # 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
   249
                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
   250
                    # 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
   251
                    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
   252
                        m = os.stat(checknoexec).st_mode
49306
2e726c934fcd py3: catch FileNotFoundError instead of checking errno == ENOENT
Manuel Jacob <me@manueljacob.de>
parents: 49305
diff changeset
   253
                    except FileNotFoundError:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   254
                        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
   255
                        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
   256
                    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
   257
                        # 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
   258
                        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
   259
                    # checknoexec exists but is exec - delete it
31537
c6cbe5720353 posix: use local reference to unlink
Ryan McElroy <rmcelroy@fb.com>
parents: 31506
diff changeset
   260
                    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
   261
                # 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
   262
                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
   263
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
            # 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
   265
            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
   266
        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
   267
            # 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
   268
            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
   269
            checkisexec = None
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   270
        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
   271
        try:
5b0a3f6cbead util: move checkexec() to posix.py and return False on Windows
Adrian Buehlmann <adrian@cadifra.com>
parents: 13400
diff changeset
   272
            os.close(fh)
30445
1ce4c2062ab0 posix: simplify checkexec check
Mads Kiilerich <madski@unity3d.com>
parents: 30444
diff changeset
   273
            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
   274
            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
   275
                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
   276
                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
   277
                    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
   278
                        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
   279
                        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
   280
                    return True
13879
5b0a3f6cbead util: move checkexec() to posix.py and return False on Windows
Adrian Buehlmann <adrian@cadifra.com>
parents: 13400
diff changeset
   281
        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
   282
            if fn is not None:
31537
c6cbe5720353 posix: use local reference to unlink
Ryan McElroy <rmcelroy@fb.com>
parents: 31506
diff changeset
   283
                unlink(fn)
13879
5b0a3f6cbead util: move checkexec() to posix.py and return False on Windows
Adrian Buehlmann <adrian@cadifra.com>
parents: 13400
diff changeset
   284
    except (IOError, OSError):
5b0a3f6cbead util: move checkexec() to posix.py and return False on Windows
Adrian Buehlmann <adrian@cadifra.com>
parents: 13400
diff changeset
   285
        # 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
   286
        return False
5b0a3f6cbead util: move checkexec() to posix.py and return False on Windows
Adrian Buehlmann <adrian@cadifra.com>
parents: 13400
diff changeset
   287
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   288
49812
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49811
diff changeset
   289
def checklink(path: bytes) -> bool:
13890
31eb145b50b6 util: move checklink() to posix.py and return False on Windows
Adrian Buehlmann <adrian@cadifra.com>
parents: 13879
diff changeset
   290
    """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
   291
    # 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
   292
    # file already exists
26883
c750ed59892a posix: retry on symlink race in checklink
Matt Mackall <mpm@selenic.com>
parents: 26248
diff changeset
   293
    while True:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   294
        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
   295
        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
   296
        # 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
   297
        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
   298
            return True
30447
0d87b1caed92 posix: move checklink test file to .hg/cache
Mads Kiilerich <madski@unity3d.com>
parents: 30446
diff changeset
   299
        if os.path.isdir(cachedir):
0d87b1caed92 posix: move checklink test file to .hg/cache
Mads Kiilerich <madski@unity3d.com>
parents: 30446
diff changeset
   300
            checkdir = cachedir
0d87b1caed92 posix: move checklink test file to .hg/cache
Mads Kiilerich <madski@unity3d.com>
parents: 30446
diff changeset
   301
        else:
0d87b1caed92 posix: move checklink test file to .hg/cache
Mads Kiilerich <madski@unity3d.com>
parents: 30446
diff changeset
   302
            checkdir = path
0d87b1caed92 posix: move checklink test file to .hg/cache
Mads Kiilerich <madski@unity3d.com>
parents: 30446
diff changeset
   303
            cachedir = None
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   304
        name = tempfile.mktemp(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   305
            dir=pycompat.fsdecode(checkdir), prefix=r'checklink-'
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   306
        )
31506
53575feed7c0 posix: tiptoe around tempfile module more delicately
Augie Fackler <augie@google.com>
parents: 31505
diff changeset
   307
        name = pycompat.fsencode(name)
22946
77c121da6143 checklink: always close the NamedTemporaryFile
Augie Fackler <raf@durin42.com>
parents: 22781
diff changeset
   308
        try:
30555
6a672c3b7860 posix: give the cached symlink a real target
Martijn Pieters <mjpieters@fb.com>
parents: 30448
diff changeset
   309
            fd = None
6a672c3b7860 posix: give the cached symlink a real target
Martijn Pieters <mjpieters@fb.com>
parents: 30448
diff changeset
   310
            if cachedir is None:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   311
                fd = pycompat.namedtempfile(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   312
                    dir=checkdir, prefix=b'hg-checklink-'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   313
                )
38166
cc9aa88792fe py3: wrap tempfile.NamedTemporaryFile() to return bytes fp.name
Yuya Nishihara <yuya@tcha.org>
parents: 38164
diff changeset
   314
                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
   315
            else:
6a672c3b7860 posix: give the cached symlink a real target
Martijn Pieters <mjpieters@fb.com>
parents: 30448
diff changeset
   316
                # 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
   317
                # already exists.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   318
                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
   319
                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
   320
                    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
   321
                    open(fullpath, b'w').close()
49307
6f2a57ba2d13 py3: catch PermissionError instead of checking errno == EACCES
Manuel Jacob <me@manueljacob.de>
parents: 49306
diff changeset
   322
                except PermissionError:
6f2a57ba2d13 py3: catch PermissionError instead of checking errno == EACCES
Manuel Jacob <me@manueljacob.de>
parents: 49306
diff changeset
   323
                    # If we can't write to cachedir, just pretend
6f2a57ba2d13 py3: catch PermissionError instead of checking errno == EACCES
Manuel Jacob <me@manueljacob.de>
parents: 49306
diff changeset
   324
                    # that the fs is readonly and by association
6f2a57ba2d13 py3: catch PermissionError instead of checking errno == EACCES
Manuel Jacob <me@manueljacob.de>
parents: 49306
diff changeset
   325
                    # that the fs won't support symlinks. This
6f2a57ba2d13 py3: catch PermissionError instead of checking errno == EACCES
Manuel Jacob <me@manueljacob.de>
parents: 49306
diff changeset
   326
                    # seems like the least dangerous way to avoid
6f2a57ba2d13 py3: catch PermissionError instead of checking errno == EACCES
Manuel Jacob <me@manueljacob.de>
parents: 49306
diff changeset
   327
                    # data loss.
6f2a57ba2d13 py3: catch PermissionError instead of checking errno == EACCES
Manuel Jacob <me@manueljacob.de>
parents: 49306
diff changeset
   328
                    return False
26883
c750ed59892a posix: retry on symlink race in checklink
Matt Mackall <mpm@selenic.com>
parents: 26248
diff changeset
   329
            try:
30555
6a672c3b7860 posix: give the cached symlink a real target
Martijn Pieters <mjpieters@fb.com>
parents: 30448
diff changeset
   330
                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
   331
                if cachedir is None:
31537
c6cbe5720353 posix: use local reference to unlink
Ryan McElroy <rmcelroy@fb.com>
parents: 31506
diff changeset
   332
                    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
   333
                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
   334
                    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
   335
                        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
   336
                    except OSError:
31537
c6cbe5720353 posix: use local reference to unlink
Ryan McElroy <rmcelroy@fb.com>
parents: 31506
diff changeset
   337
                        unlink(name)
26883
c750ed59892a posix: retry on symlink race in checklink
Matt Mackall <mpm@selenic.com>
parents: 26248
diff changeset
   338
                return True
49305
53e9422a9b45 py3: catch FileExistsError instead of checking errno == EEXIST
Manuel Jacob <me@manueljacob.de>
parents: 49302
diff changeset
   339
            except FileExistsError:
26883
c750ed59892a posix: retry on symlink race in checklink
Matt Mackall <mpm@selenic.com>
parents: 26248
diff changeset
   340
                # link creation might race, try again
49305
53e9422a9b45 py3: catch FileExistsError instead of checking errno == EEXIST
Manuel Jacob <me@manueljacob.de>
parents: 49302
diff changeset
   341
                continue
26883
c750ed59892a posix: retry on symlink race in checklink
Matt Mackall <mpm@selenic.com>
parents: 26248
diff changeset
   342
            finally:
30555
6a672c3b7860 posix: give the cached symlink a real target
Martijn Pieters <mjpieters@fb.com>
parents: 30448
diff changeset
   343
                if fd is not None:
6a672c3b7860 posix: give the cached symlink a real target
Martijn Pieters <mjpieters@fb.com>
parents: 30448
diff changeset
   344
                    fd.close()
26883
c750ed59892a posix: retry on symlink race in checklink
Matt Mackall <mpm@selenic.com>
parents: 26248
diff changeset
   345
        except AttributeError:
c750ed59892a posix: retry on symlink race in checklink
Matt Mackall <mpm@selenic.com>
parents: 26248
diff changeset
   346
            return False
26889
1aa5083cbebb posix: fix test-permissions regression
Matt Mackall <mpm@selenic.com>
parents: 26883
diff changeset
   347
        except OSError as inst:
1aa5083cbebb posix: fix test-permissions regression
Matt Mackall <mpm@selenic.com>
parents: 26883
diff changeset
   348
            # 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
   349
            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
   350
                unlink(name)
26889
1aa5083cbebb posix: fix test-permissions regression
Matt Mackall <mpm@selenic.com>
parents: 26883
diff changeset
   351
            return False
13890
31eb145b50b6 util: move checklink() to posix.py and return False on Windows
Adrian Buehlmann <adrian@cadifra.com>
parents: 13879
diff changeset
   352
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   353
13916
98ee3dd5bab4 path_auditor: check filenames for basic platform validity (issue2755)
Adrian Buehlmann <adrian@cadifra.com>
parents: 13890
diff changeset
   354
def checkosfilename(path):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45718
diff changeset
   355
    """Check that the base-relative path is a valid filename on this platform.
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45718
diff changeset
   356
    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
   357
    return None  # on posix platforms, every path is ok
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   358
13916
98ee3dd5bab4 path_auditor: check filenames for basic platform validity (issue2755)
Adrian Buehlmann <adrian@cadifra.com>
parents: 13890
diff changeset
   359
35513
c4caf530b1c7 util: add a function to show the mount point of the filesystem
Matt Harbison <matt_harbison@yahoo.com>
parents: 35509
diff changeset
   360
def getfsmountpoint(dirpath):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45718
diff changeset
   361
    """Get the filesystem mount point from a directory (best-effort)
35513
c4caf530b1c7 util: add a function to show the mount point of the filesystem
Matt Harbison <matt_harbison@yahoo.com>
parents: 35509
diff changeset
   362
c4caf530b1c7 util: add a function to show the mount point of the filesystem
Matt Harbison <matt_harbison@yahoo.com>
parents: 35509
diff changeset
   363
    Returns None if we are unsure. Raises OSError on ENOENT, EPERM, etc.
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45718
diff changeset
   364
    """
35513
c4caf530b1c7 util: add a function to show the mount point of the filesystem
Matt Harbison <matt_harbison@yahoo.com>
parents: 35509
diff changeset
   365
    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
   366
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   367
49811
0a91aba258e0 typing: add type hints to the posix platform module matching win32.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49810
diff changeset
   368
def getfstype(dirpath: bytes) -> Optional[bytes]:
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45718
diff changeset
   369
    """Get the filesystem type name from a directory (best-effort)
35509
beede158ea8a util: move getfstype() to the platform modules
Matt Harbison <matt_harbison@yahoo.com>
parents: 34647
diff changeset
   370
beede158ea8a util: move getfstype() to the platform modules
Matt Harbison <matt_harbison@yahoo.com>
parents: 34647
diff changeset
   371
    Returns None if we are unsure. Raises OSError on ENOENT, EPERM, etc.
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45718
diff changeset
   372
    """
35509
beede158ea8a util: move getfstype() to the platform modules
Matt Harbison <matt_harbison@yahoo.com>
parents: 34647
diff changeset
   373
    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
   374
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   375
49812
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49811
diff changeset
   376
def get_password() -> bytes:
47079
5b3513177f2b util: avoid echoing the password to the console on Windows py3 (issue6446)
Matt Harbison <matt_harbison@yahoo.com>
parents: 46819
diff changeset
   377
    return encoding.strtolocal(getpass.getpass(''))
5b3513177f2b util: avoid echoing the password to the console on Windows py3 (issue6446)
Matt Harbison <matt_harbison@yahoo.com>
parents: 46819
diff changeset
   378
5b3513177f2b util: avoid echoing the password to the console on Windows py3 (issue6446)
Matt Harbison <matt_harbison@yahoo.com>
parents: 46819
diff changeset
   379
49812
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49811
diff changeset
   380
def setbinary(fd) -> None:
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   381
    pass
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   382
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   383
49812
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49811
diff changeset
   384
def pconvert(path: bytes) -> bytes:
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   385
    return path
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   386
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   387
49812
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49811
diff changeset
   388
def localpath(path: bytes) -> bytes:
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   389
    return path
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   390
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   391
49811
0a91aba258e0 typing: add type hints to the posix platform module matching win32.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49810
diff changeset
   392
def samefile(fpath1: bytes, fpath2: bytes) -> bool:
10218
750b7a4f01f6 Add support for relinking on Windows.
Siddharth Agarwal <sid.bugzilla@gmail.com>
parents: 9549
diff changeset
   393
    """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
   394
    guaranteed to work for files, not directories."""
750b7a4f01f6 Add support for relinking on Windows.
Siddharth Agarwal <sid.bugzilla@gmail.com>
parents: 9549
diff changeset
   395
    return os.path.samefile(fpath1, fpath2)
750b7a4f01f6 Add support for relinking on Windows.
Siddharth Agarwal <sid.bugzilla@gmail.com>
parents: 9549
diff changeset
   396
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   397
49811
0a91aba258e0 typing: add type hints to the posix platform module matching win32.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49810
diff changeset
   398
def samedevice(fpath1: bytes, fpath2: bytes) -> bool:
10218
750b7a4f01f6 Add support for relinking on Windows.
Siddharth Agarwal <sid.bugzilla@gmail.com>
parents: 9549
diff changeset
   399
    """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
   400
    guaranteed to work for files, not directories."""
750b7a4f01f6 Add support for relinking on Windows.
Siddharth Agarwal <sid.bugzilla@gmail.com>
parents: 9549
diff changeset
   401
    st1 = os.lstat(fpath1)
750b7a4f01f6 Add support for relinking on Windows.
Siddharth Agarwal <sid.bugzilla@gmail.com>
parents: 9549
diff changeset
   402
    st2 = os.lstat(fpath2)
750b7a4f01f6 Add support for relinking on Windows.
Siddharth Agarwal <sid.bugzilla@gmail.com>
parents: 9549
diff changeset
   403
    return st1.st_dev == st2.st_dev
750b7a4f01f6 Add support for relinking on Windows.
Siddharth Agarwal <sid.bugzilla@gmail.com>
parents: 9549
diff changeset
   404
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   405
15488
6eff984d8e76 dirstate: fix case-folding identity for traditional Unix
Matt Mackall <mpm@selenic.com>
parents: 15353
diff changeset
   406
# os.path.normcase is a no-op, which doesn't help us on non-native filesystems
49812
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49811
diff changeset
   407
def normcase(path: bytes) -> bytes:
15488
6eff984d8e76 dirstate: fix case-folding identity for traditional Unix
Matt Mackall <mpm@selenic.com>
parents: 15353
diff changeset
   408
    return path.lower()
6eff984d8e76 dirstate: fix case-folding identity for traditional Unix
Matt Mackall <mpm@selenic.com>
parents: 15353
diff changeset
   409
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   410
24594
609aa973c01d posix: define normcase spec and fallback
Siddharth Agarwal <sid0@fb.com>
parents: 24108
diff changeset
   411
# what normcase does to ASCII strings
609aa973c01d posix: define normcase spec and fallback
Siddharth Agarwal <sid0@fb.com>
parents: 24108
diff changeset
   412
normcasespec = encoding.normcasespecs.lower
609aa973c01d posix: define normcase spec and fallback
Siddharth Agarwal <sid0@fb.com>
parents: 24108
diff changeset
   413
# fallback normcase function for non-ASCII strings
609aa973c01d posix: define normcase spec and fallback
Siddharth Agarwal <sid0@fb.com>
parents: 24108
diff changeset
   414
normcasefallback = normcase
609aa973c01d posix: define normcase spec and fallback
Siddharth Agarwal <sid0@fb.com>
parents: 24108
diff changeset
   415
34647
dacfcdd8b94e codemod: use pycompat.isdarwin
Jun Wu <quark@fb.com>
parents: 34383
diff changeset
   416
if pycompat.isdarwin:
15551
1fa41d1f1351 posix: add extended support for OS X path folding
Matt Mackall <mpm@selenic.com>
parents: 15499
diff changeset
   417
49812
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49811
diff changeset
   418
    def normcase(path: bytes) -> bytes:
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45718
diff changeset
   419
        """
19131
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   420
        Normalize a filename for OS X-compatible comparison:
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   421
        - escape-encode invalid characters
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   422
        - decompose to NFD
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   423
        - lowercase
23597
7a5bcd471f2e darwin: omit ignorable codepoints when normcase()ing a file path
Augie Fackler <raf@durin42.com>
parents: 22946
diff changeset
   424
        - 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
   425
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33659
diff changeset
   426
        >>> normcase(b'UPPER')
19131
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   427
        '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
   428
        >>> normcase(b'Caf\\xc3\\xa9')
19131
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   429
        '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
   430
        >>> normcase(b'\\xc3\\x89')
19131
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   431
        '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
   432
        >>> 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
   433
        '%b8%ca%c3\\xca\\xbe%c8.jpg'
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45718
diff changeset
   434
        """
19131
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   435
15551
1fa41d1f1351 posix: add extended support for OS X path folding
Matt Mackall <mpm@selenic.com>
parents: 15499
diff changeset
   436
        try:
22781
70624fda193d normcase: for darwin, use fast ASCII lower
Siddharth Agarwal <sid0@fb.com>
parents: 22246
diff changeset
   437
            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
   438
        except UnicodeDecodeError:
24595
136ab89d61cb darwin: define normcase spec and fallback
Siddharth Agarwal <sid0@fb.com>
parents: 24594
diff changeset
   439
            return normcasefallback(path)
136ab89d61cb darwin: define normcase spec and fallback
Siddharth Agarwal <sid0@fb.com>
parents: 24594
diff changeset
   440
136ab89d61cb darwin: define normcase spec and fallback
Siddharth Agarwal <sid0@fb.com>
parents: 24594
diff changeset
   441
    normcasespec = encoding.normcasespecs.lower
136ab89d61cb darwin: define normcase spec and fallback
Siddharth Agarwal <sid0@fb.com>
parents: 24594
diff changeset
   442
49812
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49811
diff changeset
   443
    def normcasefallback(path: bytes) -> bytes:
18501
a3b2dc1aa909 OS X: try cheap ascii .lower() in normcase before making full unicode dance
Mads Kiilerich <madski@unity3d.com>
parents: 18442
diff changeset
   444
        try:
15551
1fa41d1f1351 posix: add extended support for OS X path folding
Matt Mackall <mpm@selenic.com>
parents: 15499
diff changeset
   445
            u = path.decode('utf-8')
1fa41d1f1351 posix: add extended support for OS X path folding
Matt Mackall <mpm@selenic.com>
parents: 15499
diff changeset
   446
        except UnicodeDecodeError:
19131
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   447
            # 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
   448
            s = b''
26876
b8381832ce2b posix: use getutf8char to handle OS X filename percent-escaping
Matt Mackall <mpm@selenic.com>
parents: 26248
diff changeset
   449
            pos = 0
27380
c7129ed280b8 mac: fix percent-encoding of non-utf-8 characters (issue4999)
Matt Mackall <mpm@selenic.com>
parents: 27362
diff changeset
   450
            l = len(path)
26876
b8381832ce2b posix: use getutf8char to handle OS X filename percent-escaping
Matt Mackall <mpm@selenic.com>
parents: 26248
diff changeset
   451
            while pos < l:
b8381832ce2b posix: use getutf8char to handle OS X filename percent-escaping
Matt Mackall <mpm@selenic.com>
parents: 26248
diff changeset
   452
                try:
b8381832ce2b posix: use getutf8char to handle OS X filename percent-escaping
Matt Mackall <mpm@selenic.com>
parents: 26248
diff changeset
   453
                    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
   454
                    pos += len(c)
b8381832ce2b posix: use getutf8char to handle OS X filename percent-escaping
Matt Mackall <mpm@selenic.com>
parents: 26248
diff changeset
   455
                except ValueError:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   456
                    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
   457
                    pos += 1
b8381832ce2b posix: use getutf8char to handle OS X filename percent-escaping
Matt Mackall <mpm@selenic.com>
parents: 26248
diff changeset
   458
                s += c
19131
af3b651505e2 hfs+: rewrite percent-escaper (issue3918)
Matt Mackall <mpm@selenic.com>
parents: 18868
diff changeset
   459
15551
1fa41d1f1351 posix: add extended support for OS X path folding
Matt Mackall <mpm@selenic.com>
parents: 15499
diff changeset
   460
            u = s.decode('utf-8')
1fa41d1f1351 posix: add extended support for OS X path folding
Matt Mackall <mpm@selenic.com>
parents: 15499
diff changeset
   461
1fa41d1f1351 posix: add extended support for OS X path folding
Matt Mackall <mpm@selenic.com>
parents: 15499
diff changeset
   462
        # 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
   463
        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
   464
        # drop HFS+ ignored characters
7a5bcd471f2e darwin: omit ignorable codepoints when normcase()ing a file path
Augie Fackler <raf@durin42.com>
parents: 22946
diff changeset
   465
        return encoding.hfsignoreclean(enc)
15551
1fa41d1f1351 posix: add extended support for OS X path folding
Matt Mackall <mpm@selenic.com>
parents: 15499
diff changeset
   466
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   467
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   468
if pycompat.sysplatform == b'cygwin':
15711
c51c9dc13a58 cygwin: add cygwin specific normcase logic
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15672
diff changeset
   469
    # 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
   470
    # 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
   471
    # insensitive.
c51c9dc13a58 cygwin: add cygwin specific normcase logic
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15672
diff changeset
   472
c51c9dc13a58 cygwin: add cygwin specific normcase logic
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15672
diff changeset
   473
    # default mount points
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   474
    cygwinmountpoints = sorted(
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45718
diff changeset
   475
        [
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45718
diff changeset
   476
            b"/usr/bin",
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45718
diff changeset
   477
            b"/usr/lib",
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45718
diff changeset
   478
            b"/cygdrive",
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45718
diff changeset
   479
        ],
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45718
diff changeset
   480
        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
49812
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49811
diff changeset
   484
    def normcase(path: bytes) -> bytes:
15711
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.
49812
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49811
diff changeset
   510
    def checkexec(path: bytes) -> bool:
16240
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
49812
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49811
diff changeset
   516
    def checklink(path: bytes) -> bool:
16241
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
49812
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49811
diff changeset
   523
def shellquote(s: bytes) -> bytes:
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
49812
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49811
diff changeset
   536
def shellsplit(s: bytes) -> List[bytes]:
36415
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
49811
0a91aba258e0 typing: add type hints to the posix platform module matching win32.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49810
diff changeset
   541
def testpid(pid: int) -> bool:
7890
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
49812
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49811
diff changeset
   552
def isowner(st: os.stat_result) -> bool:
8657
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
49812
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49811
diff changeset
   557
def findexe(command: bytes) -> Optional[bytes]:
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45718
diff changeset
   558
    """Find executable for command searching like which does.
7890
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.
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45718
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
49812
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49811
diff changeset
   565
    def findexisting(executable: bytes) -> Optional[bytes]:
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
49811
0a91aba258e0 typing: add type hints to the posix platform module matching win32.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49810
diff changeset
   584
def setsignalhandler() -> None:
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
49812
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49811
diff changeset
   591
def statfiles(files: Sequence[bytes]) -> Iterator[Optional[os.stat_result]]:
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45718
diff changeset
   592
    """Stat each file in files. Yield each stat, or None if a file does not
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45718
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
49310
050dc8730858 py3: catch specific OSError subclasses instead of checking errno
Manuel Jacob <me@manueljacob.de>
parents: 49307
diff changeset
   601
        except (FileNotFoundError, NotADirectoryError):
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   602
            st = None
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   603
        yield st
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   604
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   605
49811
0a91aba258e0 typing: add type hints to the posix platform module matching win32.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49810
diff changeset
   606
def getuser() -> bytes:
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   607
    '''return name of current user'''
32129
f0ea0f642627 py3: make posix.getuser return a bytes
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31539
diff changeset
   608
    return pycompat.fsencode(getpass.getuser())
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   609
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   610
49812
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49811
diff changeset
   611
def username(uid: Optional[int] = None) -> Optional[bytes]:
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   612
    """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
   613
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   614
    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
   615
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   616
    if uid is None:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   617
        uid = os.getuid()
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   618
    try:
38252
a4aa77b84efd py3: make sure util.username() always returns bytes
Pulkit Goyal <7895pulkit@gmail.com>
parents: 38166
diff changeset
   619
        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
   620
    except KeyError:
38252
a4aa77b84efd py3: make sure util.username() always returns bytes
Pulkit Goyal <7895pulkit@gmail.com>
parents: 38166
diff changeset
   621
        return b'%d' % uid
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   622
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   623
49812
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49811
diff changeset
   624
def groupname(gid: Optional[int] = None) -> Optional[bytes]:
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   625
    """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
   626
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   627
    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
   628
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   629
    if gid is None:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   630
        gid = os.getgid()
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   631
    try:
41827
faa04f45b5fe py3: make sure return value of posix.groupname() is bytes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41523
diff changeset
   632
        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
   633
    except KeyError:
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.bytestr(gid)
10237
2f7a38f336f4 serve: add and use portable spawnvp replacement
Patrick Mezard <pmezard@gmail.com>
parents: 10218
diff changeset
   635
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   636
49812
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49811
diff changeset
   637
def groupmembers(name: bytes) -> List[bytes]:
11138
99eee847beaa acl: grp module is not available on windows
Patrick Mezard <pmezard@gmail.com>
parents: 11011
diff changeset
   638
    """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
   639
    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
   640
    """
41523
3ef8bec91465 py3: do a fsdecode(), fsencode() dance in posix.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41504
diff changeset
   641
    name = pycompat.fsdecode(name)
3ef8bec91465 py3: do a fsdecode(), fsencode() dance in posix.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41504
diff changeset
   642
    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
   643
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   644
49811
0a91aba258e0 typing: add type hints to the posix platform module matching win32.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49810
diff changeset
   645
def spawndetached(args: List[bytes]) -> int:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   646
    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
   647
10237
2f7a38f336f4 serve: add and use portable spawnvp replacement
Patrick Mezard <pmezard@gmail.com>
parents: 10218
diff changeset
   648
10239
8e4be44a676f Find right hg command for detached process
Patrick Mezard <pmezard@gmail.com>
parents: 10237
diff changeset
   649
def gethgcmd():
8e4be44a676f Find right hg command for detached process
Patrick Mezard <pmezard@gmail.com>
parents: 10237
diff changeset
   650
    return sys.argv[:1]
11010
18e81d42ee5c util: fix default termwidth() under Windows
Patrick Mezard <pmezard@gmail.com>
parents: 10264
diff changeset
   651
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   652
49811
0a91aba258e0 typing: add type hints to the posix platform module matching win32.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49810
diff changeset
   653
def makedir(path: bytes, notindexed: bool) -> None:
14908
e2b5605501df util: move "default" makedir to posix.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 14273
diff changeset
   654
    os.mkdir(path)
14909
c627fe32c923 util: move "default" unlinkpath to posix.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 14908
diff changeset
   655
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   656
49812
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49811
diff changeset
   657
def lookupreg(
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49811
diff changeset
   658
    key: bytes,
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49811
diff changeset
   659
    name: Optional[bytes] = None,
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49811
diff changeset
   660
    scope: Optional[Union[int, Iterable[int]]] = None,
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49811
diff changeset
   661
) -> Optional[bytes]:
14910
570ea0259b0a util: move "default" lookupreg to posix.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 14909
diff changeset
   662
    return None
14911
5b39503157fd util: move "default" hidewindow to posix.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 14910
diff changeset
   663
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   664
49811
0a91aba258e0 typing: add type hints to the posix platform module matching win32.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49810
diff changeset
   665
def hidewindow() -> None:
14911
5b39503157fd util: move "default" hidewindow to posix.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 14910
diff changeset
   666
    """Hide current shell window.
5b39503157fd util: move "default" hidewindow to posix.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 14910
diff changeset
   667
5b39503157fd util: move "default" hidewindow to posix.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 14910
diff changeset
   668
    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
   669
    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
   670
    """
5b39503157fd util: move "default" hidewindow to posix.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 14910
diff changeset
   671
    pass
14926
4e7e63fc685a util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents: 14911
diff changeset
   672
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   673
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48885
diff changeset
   674
class cachestat:
14927
2aa3e07b2f07 posix, windows: introduce cachestat
Idan Kamara <idankk86@gmail.com>
parents: 14926
diff changeset
   675
    def __init__(self, path):
2aa3e07b2f07 posix, windows: introduce cachestat
Idan Kamara <idankk86@gmail.com>
parents: 14926
diff changeset
   676
        self.stat = os.stat(path)
2aa3e07b2f07 posix, windows: introduce cachestat
Idan Kamara <idankk86@gmail.com>
parents: 14926
diff changeset
   677
2aa3e07b2f07 posix, windows: introduce cachestat
Idan Kamara <idankk86@gmail.com>
parents: 14926
diff changeset
   678
    def cacheable(self):
2aa3e07b2f07 posix, windows: introduce cachestat
Idan Kamara <idankk86@gmail.com>
parents: 14926
diff changeset
   679
        return bool(self.stat.st_ino)
2aa3e07b2f07 posix, windows: introduce cachestat
Idan Kamara <idankk86@gmail.com>
parents: 14926
diff changeset
   680
15791
a814f8fcc65a Use explicit integer division
Martin Geisler <mg@aragost.com>
parents: 15711
diff changeset
   681
    __hash__ = object.__hash__
a814f8fcc65a Use explicit integer division
Martin Geisler <mg@aragost.com>
parents: 15711
diff changeset
   682
14927
2aa3e07b2f07 posix, windows: introduce cachestat
Idan Kamara <idankk86@gmail.com>
parents: 14926
diff changeset
   683
    def __eq__(self, other):
2aa3e07b2f07 posix, windows: introduce cachestat
Idan Kamara <idankk86@gmail.com>
parents: 14926
diff changeset
   684
        try:
18442
ecba9b0e7672 posix: don't compare atime when determining if a file has changed
Siddharth Agarwal <sid0@fb.com>
parents: 18288
diff changeset
   685
            # 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
   686
            # 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
   687
            # 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
   688
            # 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
   689
            # changes.
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   690
            return (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   691
                self.stat.st_mode == other.stat.st_mode
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   692
                and self.stat.st_ino == other.stat.st_ino
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   693
                and self.stat.st_dev == other.stat.st_dev
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   694
                and self.stat.st_nlink == other.stat.st_nlink
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   695
                and self.stat.st_uid == other.stat.st_uid
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   696
                and self.stat.st_gid == other.stat.st_gid
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   697
                and self.stat.st_size == other.stat.st_size
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   698
                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
   699
                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
   700
            )
14927
2aa3e07b2f07 posix, windows: introduce cachestat
Idan Kamara <idankk86@gmail.com>
parents: 14926
diff changeset
   701
        except AttributeError:
2aa3e07b2f07 posix, windows: introduce cachestat
Idan Kamara <idankk86@gmail.com>
parents: 14926
diff changeset
   702
            return False
2aa3e07b2f07 posix, windows: introduce cachestat
Idan Kamara <idankk86@gmail.com>
parents: 14926
diff changeset
   703
2aa3e07b2f07 posix, windows: introduce cachestat
Idan Kamara <idankk86@gmail.com>
parents: 14926
diff changeset
   704
    def __ne__(self, other):
2aa3e07b2f07 posix, windows: introduce cachestat
Idan Kamara <idankk86@gmail.com>
parents: 14926
diff changeset
   705
        return not self == other
2aa3e07b2f07 posix, windows: introduce cachestat
Idan Kamara <idankk86@gmail.com>
parents: 14926
diff changeset
   706
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   707
49812
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49811
diff changeset
   708
def statislink(st: Optional[os.stat_result]) -> bool:
18868
cafa447a7d3b util: add functions to check symlink/exec bits
Bryan O'Sullivan <bryano@fb.com>
parents: 18501
diff changeset
   709
    '''check whether a stat result is a symlink'''
49812
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49811
diff changeset
   710
    return stat.S_ISLNK(st.st_mode) if st else False
18868
cafa447a7d3b util: add functions to check symlink/exec bits
Bryan O'Sullivan <bryano@fb.com>
parents: 18501
diff changeset
   711
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   712
49812
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49811
diff changeset
   713
def statisexec(st: Optional[os.stat_result]) -> bool:
18868
cafa447a7d3b util: add functions to check symlink/exec bits
Bryan O'Sullivan <bryano@fb.com>
parents: 18501
diff changeset
   714
    '''check whether a stat result is an executable file'''
49812
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49811
diff changeset
   715
    return (st.st_mode & 0o100 != 0) if st else False
22245
234e4c24b980 platform: implement readpipe()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 20202
diff changeset
   716
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   717
25420
c2ec81891502 util: add a simple poll utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24692
diff changeset
   718
def poll(fds):
c2ec81891502 util: add a simple poll utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24692
diff changeset
   719
    """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
   720
c2ec81891502 util: add a simple poll utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24692
diff changeset
   721
    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
   722
    (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
   723
c2ec81891502 util: add a simple poll utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24692
diff changeset
   724
    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
   725
    try:
49302
ee4537e365c8 py3: remove retry on EINTR errno
Manuel Jacob <me@manueljacob.de>
parents: 48946
diff changeset
   726
        res = select.select(fds, fds, fds)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   727
    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
   728
        raise NotImplementedError()
c2ec81891502 util: add a simple poll utility
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24692
diff changeset
   729
    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
   730
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   731
49812
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49811
diff changeset
   732
def readpipe(pipe) -> bytes:
22245
234e4c24b980 platform: implement readpipe()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 20202
diff changeset
   733
    """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
   734
    # 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
   735
    # 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
   736
    # that's available.
331cbf088c4c posix: implement readpipe using non-blocking I/O (issue4336)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22245
diff changeset
   737
    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
   738
    flags |= os.O_NONBLOCK
331cbf088c4c posix: implement readpipe using non-blocking I/O (issue4336)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22245
diff changeset
   739
    oldflags = fcntl.fcntl(pipe, fcntl.F_SETFL, flags)
22245
234e4c24b980 platform: implement readpipe()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 20202
diff changeset
   740
22246
331cbf088c4c posix: implement readpipe using non-blocking I/O (issue4336)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22245
diff changeset
   741
    try:
331cbf088c4c posix: implement readpipe using non-blocking I/O (issue4336)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22245
diff changeset
   742
        chunks = []
331cbf088c4c posix: implement readpipe using non-blocking I/O (issue4336)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22245
diff changeset
   743
        while True:
331cbf088c4c posix: implement readpipe using non-blocking I/O (issue4336)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22245
diff changeset
   744
            try:
331cbf088c4c posix: implement readpipe using non-blocking I/O (issue4336)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22245
diff changeset
   745
                s = pipe.read()
331cbf088c4c posix: implement readpipe using non-blocking I/O (issue4336)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22245
diff changeset
   746
                if not s:
331cbf088c4c posix: implement readpipe using non-blocking I/O (issue4336)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22245
diff changeset
   747
                    break
331cbf088c4c posix: implement readpipe using non-blocking I/O (issue4336)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22245
diff changeset
   748
                chunks.append(s)
331cbf088c4c posix: implement readpipe using non-blocking I/O (issue4336)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22245
diff changeset
   749
            except IOError:
331cbf088c4c posix: implement readpipe using non-blocking I/O (issue4336)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22245
diff changeset
   750
                break
331cbf088c4c posix: implement readpipe using non-blocking I/O (issue4336)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22245
diff changeset
   751
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   752
        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
   753
    finally:
331cbf088c4c posix: implement readpipe using non-blocking I/O (issue4336)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22245
diff changeset
   754
        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
   755
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42562
diff changeset
   756
49812
58dff81ffba1 typing: add type hints to the common posix/windows platform functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49811
diff changeset
   757
def bindunixsocket(sock, path: bytes) -> None:
29530
3239e2fdd2e2 chgserver: extract utility to bind unix domain socket to long path
Yuya Nishihara <yuya@tcha.org>
parents: 27380
diff changeset
   758
    """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
   759
    # 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
   760
    # 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
   761
    # 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
   762
    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
   763
    bakwdfd = None
45718
87c35b5a14eb posix: avoid a leaked file descriptor in a unix domain socket exception case
Matt Harbison <matt_harbison@yahoo.com>
parents: 45717
diff changeset
   764
87c35b5a14eb posix: avoid a leaked file descriptor in a unix domain socket exception case
Matt Harbison <matt_harbison@yahoo.com>
parents: 45717
diff changeset
   765
    try:
87c35b5a14eb posix: avoid a leaked file descriptor in a unix domain socket exception case
Matt Harbison <matt_harbison@yahoo.com>
parents: 45717
diff changeset
   766
        if dirname:
87c35b5a14eb posix: avoid a leaked file descriptor in a unix domain socket exception case
Matt Harbison <matt_harbison@yahoo.com>
parents: 45717
diff changeset
   767
            bakwdfd = os.open(b'.', os.O_DIRECTORY)
87c35b5a14eb posix: avoid a leaked file descriptor in a unix domain socket exception case
Matt Harbison <matt_harbison@yahoo.com>
parents: 45717
diff changeset
   768
            os.chdir(dirname)
87c35b5a14eb posix: avoid a leaked file descriptor in a unix domain socket exception case
Matt Harbison <matt_harbison@yahoo.com>
parents: 45717
diff changeset
   769
        sock.bind(basename)
87c35b5a14eb posix: avoid a leaked file descriptor in a unix domain socket exception case
Matt Harbison <matt_harbison@yahoo.com>
parents: 45717
diff changeset
   770
        if bakwdfd:
87c35b5a14eb posix: avoid a leaked file descriptor in a unix domain socket exception case
Matt Harbison <matt_harbison@yahoo.com>
parents: 45717
diff changeset
   771
            os.fchdir(bakwdfd)
87c35b5a14eb posix: avoid a leaked file descriptor in a unix domain socket exception case
Matt Harbison <matt_harbison@yahoo.com>
parents: 45717
diff changeset
   772
    finally:
87c35b5a14eb posix: avoid a leaked file descriptor in a unix domain socket exception case
Matt Harbison <matt_harbison@yahoo.com>
parents: 45717
diff changeset
   773
        if bakwdfd:
87c35b5a14eb posix: avoid a leaked file descriptor in a unix domain socket exception case
Matt Harbison <matt_harbison@yahoo.com>
parents: 45717
diff changeset
   774
            os.close(bakwdfd)