mercurial/utils/procutil.py
author Matt Harbison <matt_harbison@yahoo.com>
Fri, 25 Nov 2022 18:39:47 -0500
changeset 49793 8147abc05794
parent 49378 094a5fa3cf52
child 49810 a9faacdc5943
permissions -rw-r--r--
pytype: stop excluding mercurial/ui.py ui.extractchoices() is perhaps making assumptions that it shouldn't about the pattern always matching, but presumably we have test coverage for that. PyCharm flags the updated classes with a warning "Class xxx must implement all abstract methods", and suggests adding `abc.ABC` to the superclasses. I'm not sure why, unless it doesn't recognize the `__getattr__()` delegation pattern. Additionally, we can't unconditionally subclass `typing.BinaryIO` because that defeats the `__getattr__` delegation to the wrapped object at runtime. Instead, it has to only subclass during the type checking phase[1]. In any event, this fixes: File "/mnt/c/Users/Matt/hg/mercurial/ui.py", line 1518, in _runpager: Function subprocess.Popen.__new__ was called with the wrong arguments [wrong-arg-types] Expected: (cls, args, bufsize, executable, stdin, stdout: Optional[Union[IO, int]] = ..., ...) Actually passed: (cls, args, bufsize, stdin, stdout: Union[mercurial.utils.procutil.WriteAllWrapper, mercurial.windows.winstdout], ...) File "/mnt/c/Users/Matt/hg/mercurial/ui.py", line 1798, in extractchoices: No attribute 'group' on None [attribute-error] In Optional[Match[bytes]] File "/mnt/c/Users/Matt/hg/mercurial/ui.py", line 1799, in extractchoices: No attribute 'group' on None [attribute-error] In Optional[Match[bytes]] [1] https://stackoverflow.com/q/71365594
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
37118
5be286db5fb5 procutil: move process/executable management functions to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37117
diff changeset
     1
# procutil.py - utility for managing processes and executable environment
8226
8b2cd04a6e97 put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents: 8225
diff changeset
     2
#
8b2cd04a6e97 put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents: 8225
diff changeset
     3
#  Copyright 2005 K. Thananchayan <thananck@yahoo.com>
46819
d4ba4d51f85f contributor: change mentions of mpm to olivia
Raphaël Gomès <rgomes@octobus.net>
parents: 46784
diff changeset
     4
#  Copyright 2005-2007 Olivia Mackall <olivia@selenic.com>
8226
8b2cd04a6e97 put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents: 8225
diff changeset
     5
#  Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
8b2cd04a6e97 put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents: 8225
diff changeset
     6
#
8b2cd04a6e97 put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents: 8225
diff changeset
     7
# 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: 9996
diff changeset
     8
# GNU General Public License version 2 or any later version.
1082
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
     9
27358
ac839ee45b6a util: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27357
diff changeset
    10
37124
6715e8035b4f procutil: introduce context-manager interface for protect/restorestdio
Yuya Nishihara <yuya@tcha.org>
parents: 37123
diff changeset
    11
import contextlib
40497
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
    12
import errno
36432
1ca4e86c7265 util: handle fileno() on Python 3 throwing io.UnsupportedOperation
Augie Fackler <augie@google.com>
parents: 36422
diff changeset
    13
import io
27358
ac839ee45b6a util: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27357
diff changeset
    14
import os
ac839ee45b6a util: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27357
diff changeset
    15
import signal
ac839ee45b6a util: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27357
diff changeset
    16
import subprocess
ac839ee45b6a util: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27357
diff changeset
    17
import sys
44781
ed684a82e29b procutil: always waiting on child processes to prevent zombies with 'hg serve'
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 43912
diff changeset
    18
import threading
27358
ac839ee45b6a util: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27357
diff changeset
    19
import time
3769
96095d9ff1f8 Add encoding detection
Matt Mackall <mpm@selenic.com>
parents: 3767
diff changeset
    20
49793
8147abc05794 pytype: stop excluding mercurial/ui.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49378
diff changeset
    21
from typing import (
8147abc05794 pytype: stop excluding mercurial/ui.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49378
diff changeset
    22
    BinaryIO,
8147abc05794 pytype: stop excluding mercurial/ui.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49378
diff changeset
    23
)
8147abc05794 pytype: stop excluding mercurial/ui.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49378
diff changeset
    24
37118
5be286db5fb5 procutil: move process/executable management functions to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37117
diff changeset
    25
from ..i18n import _
43089
c59eb1560c44 py3: manually import getattr where it is needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43085
diff changeset
    26
from ..pycompat import (
c59eb1560c44 py3: manually import getattr where it is needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43085
diff changeset
    27
    getattr,
c59eb1560c44 py3: manually import getattr where it is needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43085
diff changeset
    28
    open,
c59eb1560c44 py3: manually import getattr where it is needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43085
diff changeset
    29
)
37118
5be286db5fb5 procutil: move process/executable management functions to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37117
diff changeset
    30
5be286db5fb5 procutil: move process/executable management functions to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37117
diff changeset
    31
from .. import (
27358
ac839ee45b6a util: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27357
diff changeset
    32
    encoding,
ac839ee45b6a util: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27357
diff changeset
    33
    error,
32367
a9c71d578a1c osutil: switch to policy importer
Yuya Nishihara <yuya@tcha.org>
parents: 32306
diff changeset
    34
    policy,
28818
6041fb8f2da8 pycompat: add empty and queue to handle py3 divergence
timeless <timeless@mozdev.org>
parents: 28497
diff changeset
    35
    pycompat,
49793
8147abc05794 pytype: stop excluding mercurial/ui.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49378
diff changeset
    36
    typelib,
37083
f99d64e8a4e4 stringutil: move generic string helpers to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37082
diff changeset
    37
)
3769
96095d9ff1f8 Add encoding detection
Matt Mackall <mpm@selenic.com>
parents: 3767
diff changeset
    38
43671
664e24207728 procutil: move mainfrozen() to new resourceutil.py
Martin von Zweigbergk <martinvonz@google.com>
parents: 43657
diff changeset
    39
# Import like this to keep import-checker happy
664e24207728 procutil: move mainfrozen() to new resourceutil.py
Martin von Zweigbergk <martinvonz@google.com>
parents: 43657
diff changeset
    40
from ..utils import resourceutil
664e24207728 procutil: move mainfrozen() to new resourceutil.py
Martin von Zweigbergk <martinvonz@google.com>
parents: 43657
diff changeset
    41
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43503
diff changeset
    42
osutil = policy.importmod('osutil')
32201
4462a981e8df base85: proxy through util module
Yuya Nishihara <yuya@tcha.org>
parents: 32154
diff changeset
    43
45042
c88577199023 procutil: split import and reassignment
Manuel Jacob <me@manueljacob.de>
parents: 45041
diff changeset
    44
if pycompat.iswindows:
c88577199023 procutil: split import and reassignment
Manuel Jacob <me@manueljacob.de>
parents: 45041
diff changeset
    45
    from .. import windows as platform
c88577199023 procutil: split import and reassignment
Manuel Jacob <me@manueljacob.de>
parents: 45041
diff changeset
    46
else:
c88577199023 procutil: split import and reassignment
Manuel Jacob <me@manueljacob.de>
parents: 45041
diff changeset
    47
    from .. import posix as platform
c88577199023 procutil: split import and reassignment
Manuel Jacob <me@manueljacob.de>
parents: 45041
diff changeset
    48
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
    49
30876
3a4c0905f357 util: always force line buffered stdout when stdout is a tty (BC)
Simon Farnsworth <simonfar@fb.com>
parents: 30854
diff changeset
    50
def isatty(fp):
3a4c0905f357 util: always force line buffered stdout when stdout is a tty (BC)
Simon Farnsworth <simonfar@fb.com>
parents: 30854
diff changeset
    51
    try:
3a4c0905f357 util: always force line buffered stdout when stdout is a tty (BC)
Simon Farnsworth <simonfar@fb.com>
parents: 30854
diff changeset
    52
        return fp.isatty()
3a4c0905f357 util: always force line buffered stdout when stdout is a tty (BC)
Simon Farnsworth <simonfar@fb.com>
parents: 30854
diff changeset
    53
    except AttributeError:
3a4c0905f357 util: always force line buffered stdout when stdout is a tty (BC)
Simon Farnsworth <simonfar@fb.com>
parents: 30854
diff changeset
    54
        return False
3a4c0905f357 util: always force line buffered stdout when stdout is a tty (BC)
Simon Farnsworth <simonfar@fb.com>
parents: 30854
diff changeset
    55
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
    56
46174
a1601ff3877c procutil: introduce pseudo file object that just raises EBADF
Yuya Nishihara <yuya@tcha.org>
parents: 46102
diff changeset
    57
class BadFile(io.RawIOBase):
a1601ff3877c procutil: introduce pseudo file object that just raises EBADF
Yuya Nishihara <yuya@tcha.org>
parents: 46102
diff changeset
    58
    """Dummy file object to simulate closed stdio behavior"""
a1601ff3877c procutil: introduce pseudo file object that just raises EBADF
Yuya Nishihara <yuya@tcha.org>
parents: 46102
diff changeset
    59
a1601ff3877c procutil: introduce pseudo file object that just raises EBADF
Yuya Nishihara <yuya@tcha.org>
parents: 46102
diff changeset
    60
    def readinto(self, b):
a1601ff3877c procutil: introduce pseudo file object that just raises EBADF
Yuya Nishihara <yuya@tcha.org>
parents: 46102
diff changeset
    61
        raise IOError(errno.EBADF, 'Bad file descriptor')
a1601ff3877c procutil: introduce pseudo file object that just raises EBADF
Yuya Nishihara <yuya@tcha.org>
parents: 46102
diff changeset
    62
a1601ff3877c procutil: introduce pseudo file object that just raises EBADF
Yuya Nishihara <yuya@tcha.org>
parents: 46102
diff changeset
    63
    def write(self, b):
a1601ff3877c procutil: introduce pseudo file object that just raises EBADF
Yuya Nishihara <yuya@tcha.org>
parents: 46102
diff changeset
    64
        raise IOError(errno.EBADF, 'Bad file descriptor')
a1601ff3877c procutil: introduce pseudo file object that just raises EBADF
Yuya Nishihara <yuya@tcha.org>
parents: 46102
diff changeset
    65
a1601ff3877c procutil: introduce pseudo file object that just raises EBADF
Yuya Nishihara <yuya@tcha.org>
parents: 46102
diff changeset
    66
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48913
diff changeset
    67
class LineBufferedWrapper:
45039
2bfbd7d2c204 procutil: define LineBufferedWrapper on all Python versions
Manuel Jacob <me@manueljacob.de>
parents: 45000
diff changeset
    68
    def __init__(self, orig):
2bfbd7d2c204 procutil: define LineBufferedWrapper on all Python versions
Manuel Jacob <me@manueljacob.de>
parents: 45000
diff changeset
    69
        self.orig = orig
44950
f9734b2d59cc py3: make stdout line-buffered if connected to a TTY
Manuel Jacob <me@manueljacob.de>
parents: 44867
diff changeset
    70
45039
2bfbd7d2c204 procutil: define LineBufferedWrapper on all Python versions
Manuel Jacob <me@manueljacob.de>
parents: 45000
diff changeset
    71
    def __getattr__(self, attr):
2bfbd7d2c204 procutil: define LineBufferedWrapper on all Python versions
Manuel Jacob <me@manueljacob.de>
parents: 45000
diff changeset
    72
        return getattr(self.orig, attr)
44950
f9734b2d59cc py3: make stdout line-buffered if connected to a TTY
Manuel Jacob <me@manueljacob.de>
parents: 44867
diff changeset
    73
45039
2bfbd7d2c204 procutil: define LineBufferedWrapper on all Python versions
Manuel Jacob <me@manueljacob.de>
parents: 45000
diff changeset
    74
    def write(self, s):
2bfbd7d2c204 procutil: define LineBufferedWrapper on all Python versions
Manuel Jacob <me@manueljacob.de>
parents: 45000
diff changeset
    75
        orig = self.orig
2bfbd7d2c204 procutil: define LineBufferedWrapper on all Python versions
Manuel Jacob <me@manueljacob.de>
parents: 45000
diff changeset
    76
        res = orig.write(s)
2bfbd7d2c204 procutil: define LineBufferedWrapper on all Python versions
Manuel Jacob <me@manueljacob.de>
parents: 45000
diff changeset
    77
        if s.endswith(b'\n'):
2bfbd7d2c204 procutil: define LineBufferedWrapper on all Python versions
Manuel Jacob <me@manueljacob.de>
parents: 45000
diff changeset
    78
            orig.flush()
2bfbd7d2c204 procutil: define LineBufferedWrapper on all Python versions
Manuel Jacob <me@manueljacob.de>
parents: 45000
diff changeset
    79
        return res
44950
f9734b2d59cc py3: make stdout line-buffered if connected to a TTY
Manuel Jacob <me@manueljacob.de>
parents: 44867
diff changeset
    80
45039
2bfbd7d2c204 procutil: define LineBufferedWrapper on all Python versions
Manuel Jacob <me@manueljacob.de>
parents: 45000
diff changeset
    81
48487
333a2656e981 pytype: stop excluding procutil.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 46889
diff changeset
    82
# pytype: disable=attribute-error
45039
2bfbd7d2c204 procutil: define LineBufferedWrapper on all Python versions
Manuel Jacob <me@manueljacob.de>
parents: 45000
diff changeset
    83
io.BufferedIOBase.register(LineBufferedWrapper)
48487
333a2656e981 pytype: stop excluding procutil.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 46889
diff changeset
    84
# pytype: enable=attribute-error
44950
f9734b2d59cc py3: make stdout line-buffered if connected to a TTY
Manuel Jacob <me@manueljacob.de>
parents: 44867
diff changeset
    85
f9734b2d59cc py3: make stdout line-buffered if connected to a TTY
Manuel Jacob <me@manueljacob.de>
parents: 44867
diff changeset
    86
45040
fd205a9c358a procutil: factor out conditional creation of LineBufferedWrapper
Manuel Jacob <me@manueljacob.de>
parents: 45039
diff changeset
    87
def make_line_buffered(stream):
49378
094a5fa3cf52 procutil: make stream detection in make_line_buffered more correct and strict
Manuel Jacob <me@manueljacob.de>
parents: 49084
diff changeset
    88
    # First, check if we need to wrap the stream.
094a5fa3cf52 procutil: make stream detection in make_line_buffered more correct and strict
Manuel Jacob <me@manueljacob.de>
parents: 49084
diff changeset
    89
    check_stream = stream
094a5fa3cf52 procutil: make stream detection in make_line_buffered more correct and strict
Manuel Jacob <me@manueljacob.de>
parents: 49084
diff changeset
    90
    while True:
094a5fa3cf52 procutil: make stream detection in make_line_buffered more correct and strict
Manuel Jacob <me@manueljacob.de>
parents: 49084
diff changeset
    91
        if isinstance(check_stream, WriteAllWrapper):
094a5fa3cf52 procutil: make stream detection in make_line_buffered more correct and strict
Manuel Jacob <me@manueljacob.de>
parents: 49084
diff changeset
    92
            check_stream = check_stream.orig
094a5fa3cf52 procutil: make stream detection in make_line_buffered more correct and strict
Manuel Jacob <me@manueljacob.de>
parents: 49084
diff changeset
    93
        elif pycompat.iswindows and isinstance(
094a5fa3cf52 procutil: make stream detection in make_line_buffered more correct and strict
Manuel Jacob <me@manueljacob.de>
parents: 49084
diff changeset
    94
            check_stream,
094a5fa3cf52 procutil: make stream detection in make_line_buffered more correct and strict
Manuel Jacob <me@manueljacob.de>
parents: 49084
diff changeset
    95
            # pytype: disable=module-attr
094a5fa3cf52 procutil: make stream detection in make_line_buffered more correct and strict
Manuel Jacob <me@manueljacob.de>
parents: 49084
diff changeset
    96
            platform.winstdout
094a5fa3cf52 procutil: make stream detection in make_line_buffered more correct and strict
Manuel Jacob <me@manueljacob.de>
parents: 49084
diff changeset
    97
            # pytype: enable=module-attr
094a5fa3cf52 procutil: make stream detection in make_line_buffered more correct and strict
Manuel Jacob <me@manueljacob.de>
parents: 49084
diff changeset
    98
        ):
094a5fa3cf52 procutil: make stream detection in make_line_buffered more correct and strict
Manuel Jacob <me@manueljacob.de>
parents: 49084
diff changeset
    99
            check_stream = check_stream.fp
094a5fa3cf52 procutil: make stream detection in make_line_buffered more correct and strict
Manuel Jacob <me@manueljacob.de>
parents: 49084
diff changeset
   100
        else:
094a5fa3cf52 procutil: make stream detection in make_line_buffered more correct and strict
Manuel Jacob <me@manueljacob.de>
parents: 49084
diff changeset
   101
            break
094a5fa3cf52 procutil: make stream detection in make_line_buffered more correct and strict
Manuel Jacob <me@manueljacob.de>
parents: 49084
diff changeset
   102
    if isinstance(check_stream, io.RawIOBase):
094a5fa3cf52 procutil: make stream detection in make_line_buffered more correct and strict
Manuel Jacob <me@manueljacob.de>
parents: 49084
diff changeset
   103
        # The stream is unbuffered, we don't need to emulate line buffering.
45040
fd205a9c358a procutil: factor out conditional creation of LineBufferedWrapper
Manuel Jacob <me@manueljacob.de>
parents: 45039
diff changeset
   104
        return stream
49378
094a5fa3cf52 procutil: make stream detection in make_line_buffered more correct and strict
Manuel Jacob <me@manueljacob.de>
parents: 49084
diff changeset
   105
    elif isinstance(check_stream, io.BufferedIOBase):
094a5fa3cf52 procutil: make stream detection in make_line_buffered more correct and strict
Manuel Jacob <me@manueljacob.de>
parents: 49084
diff changeset
   106
        # The stream supports some kind of buffering. We can't assume that
094a5fa3cf52 procutil: make stream detection in make_line_buffered more correct and strict
Manuel Jacob <me@manueljacob.de>
parents: 49084
diff changeset
   107
        # lines are flushed. Fall back to wrapping the stream.
094a5fa3cf52 procutil: make stream detection in make_line_buffered more correct and strict
Manuel Jacob <me@manueljacob.de>
parents: 49084
diff changeset
   108
        pass
094a5fa3cf52 procutil: make stream detection in make_line_buffered more correct and strict
Manuel Jacob <me@manueljacob.de>
parents: 49084
diff changeset
   109
    else:
094a5fa3cf52 procutil: make stream detection in make_line_buffered more correct and strict
Manuel Jacob <me@manueljacob.de>
parents: 49084
diff changeset
   110
        raise NotImplementedError(
094a5fa3cf52 procutil: make stream detection in make_line_buffered more correct and strict
Manuel Jacob <me@manueljacob.de>
parents: 49084
diff changeset
   111
            "can't determine whether stream is buffered or not"
094a5fa3cf52 procutil: make stream detection in make_line_buffered more correct and strict
Manuel Jacob <me@manueljacob.de>
parents: 49084
diff changeset
   112
        )
094a5fa3cf52 procutil: make stream detection in make_line_buffered more correct and strict
Manuel Jacob <me@manueljacob.de>
parents: 49084
diff changeset
   113
45040
fd205a9c358a procutil: factor out conditional creation of LineBufferedWrapper
Manuel Jacob <me@manueljacob.de>
parents: 45039
diff changeset
   114
    if isinstance(stream, LineBufferedWrapper):
fd205a9c358a procutil: factor out conditional creation of LineBufferedWrapper
Manuel Jacob <me@manueljacob.de>
parents: 45039
diff changeset
   115
        return stream
fd205a9c358a procutil: factor out conditional creation of LineBufferedWrapper
Manuel Jacob <me@manueljacob.de>
parents: 45039
diff changeset
   116
    return LineBufferedWrapper(stream)
fd205a9c358a procutil: factor out conditional creation of LineBufferedWrapper
Manuel Jacob <me@manueljacob.de>
parents: 45039
diff changeset
   117
fd205a9c358a procutil: factor out conditional creation of LineBufferedWrapper
Manuel Jacob <me@manueljacob.de>
parents: 45039
diff changeset
   118
45852
b56feaa9b520 chgserver: backport py3 buffered I/O workarounds from procutil
Yuya Nishihara <yuya@tcha.org>
parents: 45786
diff changeset
   119
def unwrap_line_buffered(stream):
b56feaa9b520 chgserver: backport py3 buffered I/O workarounds from procutil
Yuya Nishihara <yuya@tcha.org>
parents: 45786
diff changeset
   120
    if isinstance(stream, LineBufferedWrapper):
b56feaa9b520 chgserver: backport py3 buffered I/O workarounds from procutil
Yuya Nishihara <yuya@tcha.org>
parents: 45786
diff changeset
   121
        assert not isinstance(stream.orig, LineBufferedWrapper)
b56feaa9b520 chgserver: backport py3 buffered I/O workarounds from procutil
Yuya Nishihara <yuya@tcha.org>
parents: 45786
diff changeset
   122
        return stream.orig
b56feaa9b520 chgserver: backport py3 buffered I/O workarounds from procutil
Yuya Nishihara <yuya@tcha.org>
parents: 45786
diff changeset
   123
    return stream
b56feaa9b520 chgserver: backport py3 buffered I/O workarounds from procutil
Yuya Nishihara <yuya@tcha.org>
parents: 45786
diff changeset
   124
b56feaa9b520 chgserver: backport py3 buffered I/O workarounds from procutil
Yuya Nishihara <yuya@tcha.org>
parents: 45786
diff changeset
   125
49793
8147abc05794 pytype: stop excluding mercurial/ui.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49378
diff changeset
   126
class WriteAllWrapper(typelib.BinaryIO_Proxy):
8147abc05794 pytype: stop excluding mercurial/ui.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49378
diff changeset
   127
    def __init__(self, orig: BinaryIO):
45095
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
   128
        self.orig = orig
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
   129
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
   130
    def __getattr__(self, attr):
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
   131
        return getattr(self.orig, attr)
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
   132
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
   133
    def write(self, s):
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
   134
        write1 = self.orig.write
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
   135
        m = memoryview(s)
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
   136
        total_to_write = len(s)
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
   137
        total_written = 0
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
   138
        while total_written < total_to_write:
49068
90e564882f07 procutil: avoid `+= None` when writing to full std{err,out} descriptor on py3
Matt Harbison <matt_harbison@yahoo.com>
parents: 48488
diff changeset
   139
            c = write1(m[total_written:])
90e564882f07 procutil: avoid `+= None` when writing to full std{err,out} descriptor on py3
Matt Harbison <matt_harbison@yahoo.com>
parents: 48488
diff changeset
   140
            if c:
90e564882f07 procutil: avoid `+= None` when writing to full std{err,out} descriptor on py3
Matt Harbison <matt_harbison@yahoo.com>
parents: 48488
diff changeset
   141
                total_written += c
45095
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
   142
        return total_written
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
   143
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
   144
48487
333a2656e981 pytype: stop excluding procutil.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 46889
diff changeset
   145
# pytype: disable=attribute-error
45095
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
   146
io.IOBase.register(WriteAllWrapper)
48487
333a2656e981 pytype: stop excluding procutil.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 46889
diff changeset
   147
# pytype: enable=attribute-error
45095
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
   148
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
   149
45103
a5fa2761a6cd procutil: make _make_write_all() function private
Manuel Jacob <me@manueljacob.de>
parents: 45095
diff changeset
   150
def _make_write_all(stream):
45095
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
   151
    if isinstance(stream, WriteAllWrapper):
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
   152
        return stream
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
   153
    if isinstance(stream, io.BufferedIOBase):
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
   154
        # The io.BufferedIOBase.write() contract guarantees that all data is
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
   155
        # written.
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
   156
        return stream
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
   157
    # In general, the write() method of streams is free to write only part of
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
   158
    # the data.
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
   159
    return WriteAllWrapper(stream)
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
   160
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
   161
48910
3681b4c56618 procutil: delete Python 2 support code
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48875
diff changeset
   162
# Python 3 implements its own I/O streams. Unlike stdio of C library,
3681b4c56618 procutil: delete Python 2 support code
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48875
diff changeset
   163
# sys.stdin/stdout/stderr may be None if underlying fd is closed.
46083
81c1f5d1801f procutils: don't try to get `.buffer` if sys.stdin is None
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46030
diff changeset
   164
48910
3681b4c56618 procutil: delete Python 2 support code
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48875
diff changeset
   165
# TODO: .buffer might not exist if std streams were replaced; we'll need
3681b4c56618 procutil: delete Python 2 support code
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48875
diff changeset
   166
# a silly wrapper to make a bytes stream backed by a unicode one.
46175
a04c03b0678e procutil: assign pseudo file object if sys.stdout/stderr is missing
Yuya Nishihara <yuya@tcha.org>
parents: 46174
diff changeset
   167
48910
3681b4c56618 procutil: delete Python 2 support code
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48875
diff changeset
   168
if sys.stdin is None:
3681b4c56618 procutil: delete Python 2 support code
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48875
diff changeset
   169
    stdin = BadFile()
3681b4c56618 procutil: delete Python 2 support code
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48875
diff changeset
   170
else:
3681b4c56618 procutil: delete Python 2 support code
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48875
diff changeset
   171
    stdin = sys.stdin.buffer
3681b4c56618 procutil: delete Python 2 support code
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48875
diff changeset
   172
if sys.stdout is None:
3681b4c56618 procutil: delete Python 2 support code
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48875
diff changeset
   173
    stdout = BadFile()
45056
9694895749ad pycompat: remove pycompat.{stdin,stdout,stderr}
Manuel Jacob <me@manueljacob.de>
parents: 45045
diff changeset
   174
else:
48910
3681b4c56618 procutil: delete Python 2 support code
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48875
diff changeset
   175
    stdout = _make_write_all(sys.stdout.buffer)
3681b4c56618 procutil: delete Python 2 support code
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48875
diff changeset
   176
if sys.stderr is None:
3681b4c56618 procutil: delete Python 2 support code
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48875
diff changeset
   177
    stderr = BadFile()
3681b4c56618 procutil: delete Python 2 support code
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48875
diff changeset
   178
else:
3681b4c56618 procutil: delete Python 2 support code
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48875
diff changeset
   179
    stderr = _make_write_all(sys.stderr.buffer)
30876
3a4c0905f357 util: always force line buffered stdout when stdout is a tty (BC)
Simon Farnsworth <simonfar@fb.com>
parents: 30854
diff changeset
   180
48910
3681b4c56618 procutil: delete Python 2 support code
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48875
diff changeset
   181
if pycompat.iswindows:
3681b4c56618 procutil: delete Python 2 support code
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48875
diff changeset
   182
    # Work around Windows bugs.
3681b4c56618 procutil: delete Python 2 support code
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48875
diff changeset
   183
    stdout = platform.winstdout(stdout)  # pytype: disable=module-attr
3681b4c56618 procutil: delete Python 2 support code
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48875
diff changeset
   184
    stderr = platform.winstdout(stderr)  # pytype: disable=module-attr
3681b4c56618 procutil: delete Python 2 support code
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48875
diff changeset
   185
if isatty(stdout):
3681b4c56618 procutil: delete Python 2 support code
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48875
diff changeset
   186
    # The standard library doesn't offer line-buffered binary streams.
3681b4c56618 procutil: delete Python 2 support code
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48875
diff changeset
   187
    stdout = make_line_buffered(stdout)
14926
4e7e63fc685a util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents: 14918
diff changeset
   188
4e7e63fc685a util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents: 14918
diff changeset
   189
findexe = platform.findexe
37115
49d6ba67c93f util: mark platform-specific gethgcmd() as private
Yuya Nishihara <yuya@tcha.org>
parents: 37099
diff changeset
   190
_gethgcmd = platform.gethgcmd
14926
4e7e63fc685a util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents: 14918
diff changeset
   191
getuser = platform.getuser
28027
14033c5dd261 util: enable getpid to be replaced
timeless <timeless@mozdev.org>
parents: 27785
diff changeset
   192
getpid = os.getpid
14926
4e7e63fc685a util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents: 14918
diff changeset
   193
hidewindow = platform.hidewindow
22245
234e4c24b980 platform: implement readpipe()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21914
diff changeset
   194
readpipe = platform.readpipe
14926
4e7e63fc685a util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents: 14918
diff changeset
   195
setbinary = platform.setbinary
4e7e63fc685a util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents: 14918
diff changeset
   196
setsignalhandler = platform.setsignalhandler
4e7e63fc685a util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents: 14918
diff changeset
   197
shellquote = platform.shellquote
36415
0cb09c322647 util: factor out shellsplit() function
Yuya Nishihara <yuya@tcha.org>
parents: 36362
diff changeset
   198
shellsplit = platform.shellsplit
14926
4e7e63fc685a util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents: 14918
diff changeset
   199
spawndetached = platform.spawndetached
4e7e63fc685a util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents: 14918
diff changeset
   200
sshargs = platform.sshargs
4e7e63fc685a util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents: 14918
diff changeset
   201
testpid = platform.testpid
14912
ec46a7da9f2c util: move windows and posix wildcard imports to begin of file
Adrian Buehlmann <adrian@cadifra.com>
parents: 14911
diff changeset
   202
32208
d74b0cff94a9 osutil: proxy through util (and platform) modules (API)
Yuya Nishihara <yuya@tcha.org>
parents: 32201
diff changeset
   203
try:
d74b0cff94a9 osutil: proxy through util (and platform) modules (API)
Yuya Nishihara <yuya@tcha.org>
parents: 32201
diff changeset
   204
    setprocname = osutil.setprocname
d74b0cff94a9 osutil: proxy through util (and platform) modules (API)
Yuya Nishihara <yuya@tcha.org>
parents: 32201
diff changeset
   205
except AttributeError:
d74b0cff94a9 osutil: proxy through util (and platform) modules (API)
Yuya Nishihara <yuya@tcha.org>
parents: 32201
diff changeset
   206
    pass
35460
8652ab4046e4 osutil: add a function to unblock signals
Jun Wu <quark@fb.com>
parents: 35145
diff changeset
   207
try:
8652ab4046e4 osutil: add a function to unblock signals
Jun Wu <quark@fb.com>
parents: 35145
diff changeset
   208
    unblocksignal = osutil.unblocksignal
8652ab4046e4 osutil: add a function to unblock signals
Jun Wu <quark@fb.com>
parents: 35145
diff changeset
   209
except AttributeError:
8652ab4046e4 osutil: add a function to unblock signals
Jun Wu <quark@fb.com>
parents: 35145
diff changeset
   210
    pass
32208
d74b0cff94a9 osutil: proxy through util (and platform) modules (API)
Yuya Nishihara <yuya@tcha.org>
parents: 32201
diff changeset
   211
34646
238abf65a8ad codemod: use pycompat.isposix
Jun Wu <quark@fb.com>
parents: 34645
diff changeset
   212
closefds = pycompat.isposix
10197
29e3c4a7699b subrepo: normalize svn output line-endings
Patrick Mezard <pmezard@gmail.com>
parents: 9996
diff changeset
   213
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   214
37460
a6c6b7beb025 procutil: unify platform.explainexit()
Yuya Nishihara <yuya@tcha.org>
parents: 37459
diff changeset
   215
def explainexit(code):
37463
bbd240f81ac5 procutil: make explainexit() simply return a message (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37462
diff changeset
   216
    """return a message describing a subprocess status
37460
a6c6b7beb025 procutil: unify platform.explainexit()
Yuya Nishihara <yuya@tcha.org>
parents: 37459
diff changeset
   217
    (codes from kill are negative - not os.system/wait encoding)"""
a6c6b7beb025 procutil: unify platform.explainexit()
Yuya Nishihara <yuya@tcha.org>
parents: 37459
diff changeset
   218
    if code >= 0:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   219
        return _(b"exited with status %d") % code
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   220
    return _(b"killed by signal %d") % -code
37460
a6c6b7beb025 procutil: unify platform.explainexit()
Yuya Nishihara <yuya@tcha.org>
parents: 37459
diff changeset
   221
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   222
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48913
diff changeset
   223
class _pfile:
37459
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   224
    """File-like wrapper for a stream opened by subprocess.Popen()"""
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   225
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   226
    def __init__(self, proc, fp):
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   227
        self._proc = proc
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   228
        self._fp = fp
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   229
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   230
    def close(self):
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   231
        # unlike os.popen(), this returns an integer in subprocess coding
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   232
        self._fp.close()
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   233
        return self._proc.wait()
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   234
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   235
    def __iter__(self):
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   236
        return iter(self._fp)
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   237
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   238
    def __getattr__(self, attr):
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   239
        return getattr(self._fp, attr)
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   240
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   241
    def __enter__(self):
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   242
        return self
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   243
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   244
    def __exit__(self, exc_type, exc_value, exc_tb):
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   245
        self.close()
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   246
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   247
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   248
def popen(cmd, mode=b'rb', bufsize=-1):
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   249
    if mode == b'rb':
37459
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   250
        return _popenreader(cmd, bufsize)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   251
    elif mode == b'wb':
37459
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   252
        return _popenwriter(cmd, bufsize)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   253
    raise error.ProgrammingError(b'unsupported mode: %r' % mode)
37459
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   254
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   255
37459
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   256
def _popenreader(cmd, bufsize):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   257
    p = subprocess.Popen(
44867
8e8fd938ca07 cleanup: eliminate procutil.quotecommand()
Manuel Jacob <me@manueljacob.de>
parents: 44812
diff changeset
   258
        tonativestr(cmd),
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   259
        shell=True,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   260
        bufsize=bufsize,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   261
        close_fds=closefds,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   262
        stdout=subprocess.PIPE,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   263
    )
37459
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   264
    return _pfile(p, p.stdout)
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   265
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   266
37459
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   267
def _popenwriter(cmd, bufsize):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   268
    p = subprocess.Popen(
44867
8e8fd938ca07 cleanup: eliminate procutil.quotecommand()
Manuel Jacob <me@manueljacob.de>
parents: 44812
diff changeset
   269
        tonativestr(cmd),
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   270
        shell=True,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   271
        bufsize=bufsize,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   272
        close_fds=closefds,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   273
        stdin=subprocess.PIPE,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   274
    )
37459
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   275
    return _pfile(p, p.stdin)
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   276
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   277
37464
632b92899203 procutil: drop unused 'newlines' option from popen*() (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37463
diff changeset
   278
def popen2(cmd, env=None):
9089
8ec39725d966 util: remove unused bufsize argument
Martin Geisler <mg@lazybytes.net>
parents: 9084
diff changeset
   279
    # Setting bufsize to -1 lets the system decide the buffer size.
8ec39725d966 util: remove unused bufsize argument
Martin Geisler <mg@lazybytes.net>
parents: 9084
diff changeset
   280
    # The default for bufsize is 0, meaning unbuffered. This leads to
8ec39725d966 util: remove unused bufsize argument
Martin Geisler <mg@lazybytes.net>
parents: 9084
diff changeset
   281
    # poor performance on Mac OS X: http://bugs.python.org/issue4194
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   282
    p = subprocess.Popen(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   283
        tonativestr(cmd),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   284
        shell=True,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   285
        bufsize=-1,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   286
        close_fds=closefds,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   287
        stdin=subprocess.PIPE,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   288
        stdout=subprocess.PIPE,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   289
        env=tonativeenv(env),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   290
    )
8280
0b02d98d44d0 util: always use subprocess
Martin Geisler <mg@lazybytes.net>
parents: 8257
diff changeset
   291
    return p.stdin, p.stdout
10197
29e3c4a7699b subrepo: normalize svn output line-endings
Patrick Mezard <pmezard@gmail.com>
parents: 9996
diff changeset
   292
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   293
37464
632b92899203 procutil: drop unused 'newlines' option from popen*() (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37463
diff changeset
   294
def popen3(cmd, env=None):
632b92899203 procutil: drop unused 'newlines' option from popen*() (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37463
diff changeset
   295
    stdin, stdout, stderr, p = popen4(cmd, env)
18759
9baf4330d88f sshpeer: store subprocess so it cleans up correctly
Durham Goode <durham@fb.com>
parents: 18736
diff changeset
   296
    return stdin, stdout, stderr
9baf4330d88f sshpeer: store subprocess so it cleans up correctly
Durham Goode <durham@fb.com>
parents: 18736
diff changeset
   297
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   298
37464
632b92899203 procutil: drop unused 'newlines' option from popen*() (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37463
diff changeset
   299
def popen4(cmd, env=None, bufsize=-1):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   300
    p = subprocess.Popen(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   301
        tonativestr(cmd),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   302
        shell=True,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   303
        bufsize=bufsize,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   304
        close_fds=closefds,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   305
        stdin=subprocess.PIPE,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   306
        stdout=subprocess.PIPE,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   307
        stderr=subprocess.PIPE,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   308
        env=tonativeenv(env),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   309
    )
18759
9baf4330d88f sshpeer: store subprocess so it cleans up correctly
Durham Goode <durham@fb.com>
parents: 18736
diff changeset
   310
    return p.stdin, p.stdout, p.stderr, p
7106
4674706b5b95 python2.6: use subprocess if available
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6884
diff changeset
   311
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   312
1293
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   313
def pipefilter(s, cmd):
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   314
    '''filter string S through command CMD, returning its output'''
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   315
    p = subprocess.Popen(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   316
        tonativestr(cmd),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   317
        shell=True,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   318
        close_fds=closefds,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   319
        stdin=subprocess.PIPE,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   320
        stdout=subprocess.PIPE,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   321
    )
8302
d2ad8c066676 util: simplify pipefilter and avoid subprocess race
Martin Geisler <mg@lazybytes.net>
parents: 8299
diff changeset
   322
    pout, perr = p.communicate(s)
d2ad8c066676 util: simplify pipefilter and avoid subprocess race
Martin Geisler <mg@lazybytes.net>
parents: 8299
diff changeset
   323
    return pout
419
28511fc21073 [PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff changeset
   324
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   325
1293
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   326
def tempfilter(s, cmd):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45852
diff changeset
   327
    """filter string S through a pair of temporary files with CMD.
1293
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   328
    CMD is used as a template to create the real command to be run,
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   329
    with the strings INFILE and OUTFILE replaced by the real names of
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45852
diff changeset
   330
    the temporary files generated."""
1293
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   331
    inname, outname = None, None
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   332
    try:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   333
        infd, inname = pycompat.mkstemp(prefix=b'hg-filter-in-')
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43503
diff changeset
   334
        fp = os.fdopen(infd, 'wb')
1293
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   335
        fp.write(s)
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   336
        fp.close()
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   337
        outfd, outname = pycompat.mkstemp(prefix=b'hg-filter-out-')
1293
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   338
        os.close(outfd)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   339
        cmd = cmd.replace(b'INFILE', inname)
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   340
        cmd = cmd.replace(b'OUTFILE', outname)
37461
538353b80676 procutil: fix error message of tempfile filter
Yuya Nishihara <yuya@tcha.org>
parents: 37460
diff changeset
   341
        code = system(cmd)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   342
        if pycompat.sysplatform == b'OpenVMS' and code & 1:
4720
72fb6f10fac1 OpenVMS patches
Jean-Francois PIERONNE <jf.pieronne@laposte.net>
parents: 4708
diff changeset
   343
            code = 0
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
   344
        if code:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   345
            raise error.Abort(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   346
                _(b"command '%s' failed: %s") % (cmd, explainexit(code))
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   347
            )
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   348
        with open(outname, b'rb') as fp:
37117
e7b517809ebc util: stop using readfile() in tempfilter()
Yuya Nishihara <yuya@tcha.org>
parents: 37116
diff changeset
   349
            return fp.read()
1293
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   350
    finally:
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   351
        try:
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
   352
            if inname:
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
   353
                os.unlink(inname)
14004
97ed99d1f419 eliminate various naked except clauses
Idan Kamara <idankk86@gmail.com>
parents: 13985
diff changeset
   354
        except OSError:
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
   355
            pass
1293
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   356
        try:
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
   357
            if outname:
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
   358
                os.unlink(outname)
14004
97ed99d1f419 eliminate various naked except clauses
Idan Kamara <idankk86@gmail.com>
parents: 13985
diff changeset
   359
        except OSError:
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
   360
            pass
1293
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   361
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   362
37116
7ccc9b8aca4c util: mark filtertable as private constant
Yuya Nishihara <yuya@tcha.org>
parents: 37115
diff changeset
   363
_filtertable = {
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   364
    b'tempfile:': tempfilter,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   365
    b'pipe:': pipefilter,
37116
7ccc9b8aca4c util: mark filtertable as private constant
Yuya Nishihara <yuya@tcha.org>
parents: 37115
diff changeset
   366
}
1293
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   367
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   368
1293
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   369
def filter(s, cmd):
43787
be8552f25cab cleanup: fix docstring formatting
Matt Harbison <matt_harbison@yahoo.com>
parents: 43671
diff changeset
   370
    """filter a string through a command that transforms its input to its
be8552f25cab cleanup: fix docstring formatting
Matt Harbison <matt_harbison@yahoo.com>
parents: 43671
diff changeset
   371
    output"""
48913
f254fc73d956 global: bulk replace simple pycompat.iteritems(x) with x.items()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48910
diff changeset
   372
    for name, fn in _filtertable.items():
1293
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   373
        if cmd.startswith(name):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   374
            return fn(s, cmd[len(name) :].lstrip())
1293
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   375
    return pipefilter(s, cmd)
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   376
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   377
22632
db15bb2d6323 util: move _hgexecutable a few lines, closer to where it is used
Mads Kiilerich <madski@unity3d.com>
parents: 22245
diff changeset
   378
_hgexecutable = None
db15bb2d6323 util: move _hgexecutable a few lines, closer to where it is used
Mads Kiilerich <madski@unity3d.com>
parents: 22245
diff changeset
   379
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   380
5062
3d35c8cb5eb4 Simplify/correct finding the hg executable (fixes issue644)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4832
diff changeset
   381
def hgexecutable():
3d35c8cb5eb4 Simplify/correct finding the hg executable (fixes issue644)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4832
diff changeset
   382
    """return location of the 'hg' executable.
3d35c8cb5eb4 Simplify/correct finding the hg executable (fixes issue644)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4832
diff changeset
   383
3d35c8cb5eb4 Simplify/correct finding the hg executable (fixes issue644)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4832
diff changeset
   384
    Defaults to $HG or 'hg' in the search path.
3d35c8cb5eb4 Simplify/correct finding the hg executable (fixes issue644)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4832
diff changeset
   385
    """
3d35c8cb5eb4 Simplify/correct finding the hg executable (fixes issue644)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4832
diff changeset
   386
    if _hgexecutable is None:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   387
        hg = encoding.environ.get(b'HG')
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43503
diff changeset
   388
        mainmod = sys.modules['__main__']
6500
a3175cd7dbec Tidy code, fix typo
Bryan O'Sullivan <bos@serpentine.com>
parents: 6499
diff changeset
   389
        if hg:
14229
85fd8402cbc4 rename util.set_hgexecutable to _sethgexecutable
Adrian Buehlmann <adrian@cadifra.com>
parents: 14228
diff changeset
   390
            _sethgexecutable(hg)
43671
664e24207728 procutil: move mainfrozen() to new resourceutil.py
Martin von Zweigbergk <martinvonz@google.com>
parents: 43657
diff changeset
   391
        elif resourceutil.mainfrozen():
43657
38387f9e4d22 py3: use native string for 'macosx_app'
Martin von Zweigbergk <martinvonz@google.com>
parents: 43656
diff changeset
   392
            if getattr(sys, 'frozen', None) == 'macosx_app':
27765
f1fb93eebb1d util: adjust hgexecutable() to handle frozen Mercurial on OS X
Matt Harbison <matt_harbison@yahoo.com>
parents: 27764
diff changeset
   393
                # Env variable set by py2app
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   394
                _sethgexecutable(encoding.environ[b'EXECUTABLEPATH'])
27765
f1fb93eebb1d util: adjust hgexecutable() to handle frozen Mercurial on OS X
Matt Harbison <matt_harbison@yahoo.com>
parents: 27764
diff changeset
   395
            else:
30669
10b17ed9b591 py3: replace sys.executable with pycompat.sysexecutable
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30642
diff changeset
   396
                _sethgexecutable(pycompat.sysexecutable)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   397
        elif (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   398
            not pycompat.iswindows
43656
47d983f0af65 py3: drop an unnecessary fsencode() before comparing with constant
Martin von Zweigbergk <martinvonz@google.com>
parents: 43655
diff changeset
   399
            and os.path.basename(getattr(mainmod, '__file__', '')) == 'hg'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   400
        ):
31074
2912b06905dc py3: use pycompat.fsencode() to convert __file__ to bytes
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30988
diff changeset
   401
            _sethgexecutable(pycompat.fsencode(mainmod.__file__))
6499
479847ccabe0 Added hgexecutable support for py2exe/frozen scripts
"Paul Moore <p.f.moore@gmail.com>"
parents: 5659
diff changeset
   402
        else:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   403
            _sethgexecutable(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   404
                findexe(b'hg') or os.path.basename(pycompat.sysargv[0])
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   405
            )
5062
3d35c8cb5eb4 Simplify/correct finding the hg executable (fixes issue644)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4832
diff changeset
   406
    return _hgexecutable
4686
849f011dbf79 Remember path to 'hg' executable and pass to external tools and hooks as $HG.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4673
diff changeset
   407
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   408
14229
85fd8402cbc4 rename util.set_hgexecutable to _sethgexecutable
Adrian Buehlmann <adrian@cadifra.com>
parents: 14228
diff changeset
   409
def _sethgexecutable(path):
5062
3d35c8cb5eb4 Simplify/correct finding the hg executable (fixes issue644)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4832
diff changeset
   410
    """set location of the 'hg' executable"""
4686
849f011dbf79 Remember path to 'hg' executable and pass to external tools and hooks as $HG.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4673
diff changeset
   411
    global _hgexecutable
5062
3d35c8cb5eb4 Simplify/correct finding the hg executable (fixes issue644)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4832
diff changeset
   412
    _hgexecutable = path
4686
849f011dbf79 Remember path to 'hg' executable and pass to external tools and hooks as $HG.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4673
diff changeset
   413
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   414
36793
eca1051e6c22 util: add public isstdin/isstdout() functions
Yuya Nishihara <yuya@tcha.org>
parents: 36791
diff changeset
   415
def _testfileno(f, stdf):
26450
1138e1d05207 util.system: compare fileno to see if it needs stdout redirection
Yuya Nishihara <yuya@tcha.org>
parents: 26392
diff changeset
   416
    fileno = getattr(f, 'fileno', None)
36432
1ca4e86c7265 util: handle fileno() on Python 3 throwing io.UnsupportedOperation
Augie Fackler <augie@google.com>
parents: 36422
diff changeset
   417
    try:
36793
eca1051e6c22 util: add public isstdin/isstdout() functions
Yuya Nishihara <yuya@tcha.org>
parents: 36791
diff changeset
   418
        return fileno and fileno() == stdf.fileno()
36432
1ca4e86c7265 util: handle fileno() on Python 3 throwing io.UnsupportedOperation
Augie Fackler <augie@google.com>
parents: 36422
diff changeset
   419
    except io.UnsupportedOperation:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   420
        return False  # fileno() raised UnsupportedOperation
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   421
26450
1138e1d05207 util.system: compare fileno to see if it needs stdout redirection
Yuya Nishihara <yuya@tcha.org>
parents: 26392
diff changeset
   422
36793
eca1051e6c22 util: add public isstdin/isstdout() functions
Yuya Nishihara <yuya@tcha.org>
parents: 36791
diff changeset
   423
def isstdin(f):
eca1051e6c22 util: add public isstdin/isstdout() functions
Yuya Nishihara <yuya@tcha.org>
parents: 36791
diff changeset
   424
    return _testfileno(f, sys.__stdin__)
eca1051e6c22 util: add public isstdin/isstdout() functions
Yuya Nishihara <yuya@tcha.org>
parents: 36791
diff changeset
   425
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   426
36793
eca1051e6c22 util: add public isstdin/isstdout() functions
Yuya Nishihara <yuya@tcha.org>
parents: 36791
diff changeset
   427
def isstdout(f):
eca1051e6c22 util: add public isstdin/isstdout() functions
Yuya Nishihara <yuya@tcha.org>
parents: 36791
diff changeset
   428
    return _testfileno(f, sys.__stdout__)
eca1051e6c22 util: add public isstdin/isstdout() functions
Yuya Nishihara <yuya@tcha.org>
parents: 36791
diff changeset
   429
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   430
37123
0216232f21ab procutil: move protectio/restoreio from commandserver
Yuya Nishihara <yuya@tcha.org>
parents: 37118
diff changeset
   431
def protectstdio(uin, uout):
37220
7f78de1c93aa procutil: redirect ui.fout to stderr while stdio is protected
Yuya Nishihara <yuya@tcha.org>
parents: 37219
diff changeset
   432
    """Duplicate streams and redirect original if (uin, uout) are stdio
7f78de1c93aa procutil: redirect ui.fout to stderr while stdio is protected
Yuya Nishihara <yuya@tcha.org>
parents: 37219
diff changeset
   433
7f78de1c93aa procutil: redirect ui.fout to stderr while stdio is protected
Yuya Nishihara <yuya@tcha.org>
parents: 37219
diff changeset
   434
    If uin is stdin, it's redirected to /dev/null. If uout is stdout, it's
7f78de1c93aa procutil: redirect ui.fout to stderr while stdio is protected
Yuya Nishihara <yuya@tcha.org>
parents: 37219
diff changeset
   435
    redirected to stderr so the output is still readable.
37123
0216232f21ab procutil: move protectio/restoreio from commandserver
Yuya Nishihara <yuya@tcha.org>
parents: 37118
diff changeset
   436
0216232f21ab procutil: move protectio/restoreio from commandserver
Yuya Nishihara <yuya@tcha.org>
parents: 37118
diff changeset
   437
    Returns (fin, fout) which point to the original (uin, uout) fds, but
0216232f21ab procutil: move protectio/restoreio from commandserver
Yuya Nishihara <yuya@tcha.org>
parents: 37118
diff changeset
   438
    may be copy of (uin, uout). The returned streams can be considered
0216232f21ab procutil: move protectio/restoreio from commandserver
Yuya Nishihara <yuya@tcha.org>
parents: 37118
diff changeset
   439
    "owned" in that print(), exec(), etc. never reach to them.
0216232f21ab procutil: move protectio/restoreio from commandserver
Yuya Nishihara <yuya@tcha.org>
parents: 37118
diff changeset
   440
    """
0216232f21ab procutil: move protectio/restoreio from commandserver
Yuya Nishihara <yuya@tcha.org>
parents: 37118
diff changeset
   441
    uout.flush()
37219
ac71cbad5da3 procutil: unroll uin/uout loop in protectstdio()
Yuya Nishihara <yuya@tcha.org>
parents: 37124
diff changeset
   442
    fin, fout = uin, uout
39807
e5724be689b3 procutil: compare fd number to see if stdio protection is needed (issue5992)
Yuya Nishihara <yuya@tcha.org>
parents: 38526
diff changeset
   443
    if _testfileno(uin, stdin):
37219
ac71cbad5da3 procutil: unroll uin/uout loop in protectstdio()
Yuya Nishihara <yuya@tcha.org>
parents: 37124
diff changeset
   444
        newfd = os.dup(uin.fileno())
37220
7f78de1c93aa procutil: redirect ui.fout to stderr while stdio is protected
Yuya Nishihara <yuya@tcha.org>
parents: 37219
diff changeset
   445
        nullfd = os.open(os.devnull, os.O_RDONLY)
37219
ac71cbad5da3 procutil: unroll uin/uout loop in protectstdio()
Yuya Nishihara <yuya@tcha.org>
parents: 37124
diff changeset
   446
        os.dup2(nullfd, uin.fileno())
37220
7f78de1c93aa procutil: redirect ui.fout to stderr while stdio is protected
Yuya Nishihara <yuya@tcha.org>
parents: 37219
diff changeset
   447
        os.close(nullfd)
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43503
diff changeset
   448
        fin = os.fdopen(newfd, 'rb')
39807
e5724be689b3 procutil: compare fd number to see if stdio protection is needed (issue5992)
Yuya Nishihara <yuya@tcha.org>
parents: 38526
diff changeset
   449
    if _testfileno(uout, stdout):
37219
ac71cbad5da3 procutil: unroll uin/uout loop in protectstdio()
Yuya Nishihara <yuya@tcha.org>
parents: 37124
diff changeset
   450
        newfd = os.dup(uout.fileno())
37220
7f78de1c93aa procutil: redirect ui.fout to stderr while stdio is protected
Yuya Nishihara <yuya@tcha.org>
parents: 37219
diff changeset
   451
        os.dup2(stderr.fileno(), uout.fileno())
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43503
diff changeset
   452
        fout = os.fdopen(newfd, 'wb')
37219
ac71cbad5da3 procutil: unroll uin/uout loop in protectstdio()
Yuya Nishihara <yuya@tcha.org>
parents: 37124
diff changeset
   453
    return fin, fout
37123
0216232f21ab procutil: move protectio/restoreio from commandserver
Yuya Nishihara <yuya@tcha.org>
parents: 37118
diff changeset
   454
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   455
37123
0216232f21ab procutil: move protectio/restoreio from commandserver
Yuya Nishihara <yuya@tcha.org>
parents: 37118
diff changeset
   456
def restorestdio(uin, uout, fin, fout):
0216232f21ab procutil: move protectio/restoreio from commandserver
Yuya Nishihara <yuya@tcha.org>
parents: 37118
diff changeset
   457
    """Restore (uin, uout) streams from possibly duplicated (fin, fout)"""
0216232f21ab procutil: move protectio/restoreio from commandserver
Yuya Nishihara <yuya@tcha.org>
parents: 37118
diff changeset
   458
    uout.flush()
0216232f21ab procutil: move protectio/restoreio from commandserver
Yuya Nishihara <yuya@tcha.org>
parents: 37118
diff changeset
   459
    for f, uif in [(fin, uin), (fout, uout)]:
0216232f21ab procutil: move protectio/restoreio from commandserver
Yuya Nishihara <yuya@tcha.org>
parents: 37118
diff changeset
   460
        if f is not uif:
0216232f21ab procutil: move protectio/restoreio from commandserver
Yuya Nishihara <yuya@tcha.org>
parents: 37118
diff changeset
   461
            os.dup2(f.fileno(), uif.fileno())
0216232f21ab procutil: move protectio/restoreio from commandserver
Yuya Nishihara <yuya@tcha.org>
parents: 37118
diff changeset
   462
            f.close()
0216232f21ab procutil: move protectio/restoreio from commandserver
Yuya Nishihara <yuya@tcha.org>
parents: 37118
diff changeset
   463
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   464
30736
d9e5b0aeeb90 util: extract the logic calculating environment variables
Jun Wu <quark@fb.com>
parents: 30669
diff changeset
   465
def shellenviron(environ=None):
d9e5b0aeeb90 util: extract the logic calculating environment variables
Jun Wu <quark@fb.com>
parents: 30669
diff changeset
   466
    """return environ with optional override, useful for shelling out"""
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   467
30736
d9e5b0aeeb90 util: extract the logic calculating environment variables
Jun Wu <quark@fb.com>
parents: 30669
diff changeset
   468
    def py2shell(val):
43787
be8552f25cab cleanup: fix docstring formatting
Matt Harbison <matt_harbison@yahoo.com>
parents: 43671
diff changeset
   469
        """convert python object into string that is useful to shell"""
30736
d9e5b0aeeb90 util: extract the logic calculating environment variables
Jun Wu <quark@fb.com>
parents: 30669
diff changeset
   470
        if val is None or val is False:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   471
            return b'0'
30736
d9e5b0aeeb90 util: extract the logic calculating environment variables
Jun Wu <quark@fb.com>
parents: 30669
diff changeset
   472
        if val is True:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   473
            return b'1'
36418
d26b0bedfaa4 util: use pycompat.bytestr() instead of str()
Augie Fackler <augie@google.com>
parents: 36415
diff changeset
   474
        return pycompat.bytestr(val)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   475
30736
d9e5b0aeeb90 util: extract the logic calculating environment variables
Jun Wu <quark@fb.com>
parents: 30669
diff changeset
   476
    env = dict(encoding.environ)
d9e5b0aeeb90 util: extract the logic calculating environment variables
Jun Wu <quark@fb.com>
parents: 30669
diff changeset
   477
    if environ:
48913
f254fc73d956 global: bulk replace simple pycompat.iteritems(x) with x.items()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48910
diff changeset
   478
        env.update((k, py2shell(v)) for k, v in environ.items())
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   479
    env[b'HG'] = hgexecutable()
30736
d9e5b0aeeb90 util: extract the logic calculating environment variables
Jun Wu <quark@fb.com>
parents: 30669
diff changeset
   480
    return env
d9e5b0aeeb90 util: extract the logic calculating environment variables
Jun Wu <quark@fb.com>
parents: 30669
diff changeset
   481
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   482
38491
72286f9e324f procutil: add a shim for translating shell commands to native commands
Matt Harbison <matt_harbison@yahoo.com>
parents: 38454
diff changeset
   483
if pycompat.iswindows:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   484
38491
72286f9e324f procutil: add a shim for translating shell commands to native commands
Matt Harbison <matt_harbison@yahoo.com>
parents: 38454
diff changeset
   485
    def shelltonative(cmd, env):
43478
54f4d094bab1 procutil: suppress pytype warnings around windows-only attributes
Augie Fackler <augie@google.com>
parents: 43165
diff changeset
   486
        return platform.shelltocmdexe(  # pytype: disable=module-attr
54f4d094bab1 procutil: suppress pytype warnings around windows-only attributes
Augie Fackler <augie@google.com>
parents: 43165
diff changeset
   487
            cmd, shellenviron(env)
54f4d094bab1 procutil: suppress pytype warnings around windows-only attributes
Augie Fackler <augie@google.com>
parents: 43165
diff changeset
   488
        )
39662
50f46b771921 py3: partially fix pager spawning on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 38526
diff changeset
   489
50f46b771921 py3: partially fix pager spawning on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 38526
diff changeset
   490
    tonativestr = encoding.strfromlocal
38491
72286f9e324f procutil: add a shim for translating shell commands to native commands
Matt Harbison <matt_harbison@yahoo.com>
parents: 38454
diff changeset
   491
else:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   492
38491
72286f9e324f procutil: add a shim for translating shell commands to native commands
Matt Harbison <matt_harbison@yahoo.com>
parents: 38454
diff changeset
   493
    def shelltonative(cmd, env):
72286f9e324f procutil: add a shim for translating shell commands to native commands
Matt Harbison <matt_harbison@yahoo.com>
parents: 38454
diff changeset
   494
        return cmd
72286f9e324f procutil: add a shim for translating shell commands to native commands
Matt Harbison <matt_harbison@yahoo.com>
parents: 38454
diff changeset
   495
39662
50f46b771921 py3: partially fix pager spawning on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 38526
diff changeset
   496
    tonativestr = pycompat.identity
50f46b771921 py3: partially fix pager spawning on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 38526
diff changeset
   497
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   498
39662
50f46b771921 py3: partially fix pager spawning on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 38526
diff changeset
   499
def tonativeenv(env):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45852
diff changeset
   500
    """convert the environment from bytes to strings suitable for Popen(), etc."""
39662
50f46b771921 py3: partially fix pager spawning on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 38526
diff changeset
   501
    return pycompat.rapply(tonativestr, env)
50f46b771921 py3: partially fix pager spawning on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 38526
diff changeset
   502
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   503
31108
3f8f53190d6a chg: deduplicate error handling of ui.system()
Yuya Nishihara <yuya@tcha.org>
parents: 31074
diff changeset
   504
def system(cmd, environ=None, cwd=None, out=None):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45852
diff changeset
   505
    """enhanced shell command execution.
1882
c0320567931f merge util.esystem and util.system.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1880
diff changeset
   506
    run with environment maybe modified, maybe in different dir.
508
42a660abaf75 [PATCH] Harden os.system
mpm@selenic.com
parents: 464
diff changeset
   507
11469
c37f35d7f2f5 http: deliver hook output to client
Maxim Khitrov <mkhitrov@gmail.com>
parents: 11297
diff changeset
   508
    if out is specified, it is assumed to be a file-like object that has a
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45852
diff changeset
   509
    write() method. stdout and stderr will be redirected to out."""
13439
d724a69309e0 util: flush stdout before calling external processes
Mads Kiilerich <mads@kiilerich.com>
parents: 13400
diff changeset
   510
    try:
30473
39d13b8c101d py3: bulk replace sys.stdin/out/err by util's
Yuya Nishihara <yuya@tcha.org>
parents: 30472
diff changeset
   511
        stdout.flush()
13439
d724a69309e0 util: flush stdout before calling external processes
Mads Kiilerich <mads@kiilerich.com>
parents: 13400
diff changeset
   512
    except Exception:
d724a69309e0 util: flush stdout before calling external processes
Mads Kiilerich <mads@kiilerich.com>
parents: 13400
diff changeset
   513
        pass
32886
19b0fd4b5570 plan9: drop py26 hacks
Matt Harbison <matt_harbison@yahoo.com>
parents: 32816
diff changeset
   514
    env = shellenviron(environ)
36793
eca1051e6c22 util: add public isstdin/isstdout() functions
Yuya Nishihara <yuya@tcha.org>
parents: 36791
diff changeset
   515
    if out is None or isstdout(out):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   516
        rc = subprocess.call(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   517
            tonativestr(cmd),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   518
            shell=True,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   519
            close_fds=closefds,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   520
            env=tonativeenv(env),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   521
            cwd=pycompat.rapply(tonativestr, cwd),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   522
        )
11469
c37f35d7f2f5 http: deliver hook output to client
Maxim Khitrov <mkhitrov@gmail.com>
parents: 11297
diff changeset
   523
    else:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   524
        proc = subprocess.Popen(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   525
            tonativestr(cmd),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   526
            shell=True,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   527
            close_fds=closefds,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   528
            env=tonativeenv(env),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   529
            cwd=pycompat.rapply(tonativestr, cwd),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   530
            stdout=subprocess.PIPE,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   531
            stderr=subprocess.STDOUT,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   532
        )
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   533
        for line in iter(proc.stdout.readline, b''):
32886
19b0fd4b5570 plan9: drop py26 hacks
Matt Harbison <matt_harbison@yahoo.com>
parents: 32816
diff changeset
   534
            out.write(line)
19b0fd4b5570 plan9: drop py26 hacks
Matt Harbison <matt_harbison@yahoo.com>
parents: 32816
diff changeset
   535
        proc.wait()
19b0fd4b5570 plan9: drop py26 hacks
Matt Harbison <matt_harbison@yahoo.com>
parents: 32816
diff changeset
   536
        rc = proc.returncode
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   537
    if pycompat.sysplatform == b'OpenVMS' and rc & 1:
32886
19b0fd4b5570 plan9: drop py26 hacks
Matt Harbison <matt_harbison@yahoo.com>
parents: 32816
diff changeset
   538
        rc = 0
9517
4368f582c806 util.system: Use subprocess instead of os.system
Mads Kiilerich <mads@kiilerich.com>
parents: 9508
diff changeset
   539
    return rc
1880
05c7d75be925 fix broken environment save/restore when a hook runs.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1877
diff changeset
   540
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   541
43912
a89381e04c58 procutil: try and avoid angering CoreFoundation on macOS
Augie Fackler <augie@google.com>
parents: 43862
diff changeset
   542
_is_gui = None
a89381e04c58 procutil: try and avoid angering CoreFoundation on macOS
Augie Fackler <augie@google.com>
parents: 43862
diff changeset
   543
a89381e04c58 procutil: try and avoid angering CoreFoundation on macOS
Augie Fackler <augie@google.com>
parents: 43862
diff changeset
   544
a89381e04c58 procutil: try and avoid angering CoreFoundation on macOS
Augie Fackler <augie@google.com>
parents: 43862
diff changeset
   545
def _gui():
6007
090b1a665901 filemerge: add config item for GUI tools
Matt Mackall <mpm@selenic.com>
parents: 6006
diff changeset
   546
    '''Are we running in a GUI?'''
34647
dacfcdd8b94e codemod: use pycompat.isdarwin
Jun Wu <quark@fb.com>
parents: 34646
diff changeset
   547
    if pycompat.isdarwin:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   548
        if b'SSH_CONNECTION' in encoding.environ:
13734
16118b4859a1 util: add Mac-specific check whether we're in a GUI session (issue2553)
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 13439
diff changeset
   549
            # handle SSH access to a box where the user is logged in
16118b4859a1 util: add Mac-specific check whether we're in a GUI session (issue2553)
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 13439
diff changeset
   550
            return False
16118b4859a1 util: add Mac-specific check whether we're in a GUI session (issue2553)
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 13439
diff changeset
   551
        elif getattr(osutil, 'isgui', None):
16118b4859a1 util: add Mac-specific check whether we're in a GUI session (issue2553)
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 13439
diff changeset
   552
            # check if a CoreGraphics session is available
16118b4859a1 util: add Mac-specific check whether we're in a GUI session (issue2553)
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 13439
diff changeset
   553
            return osutil.isgui()
16118b4859a1 util: add Mac-specific check whether we're in a GUI session (issue2553)
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 13439
diff changeset
   554
        else:
16118b4859a1 util: add Mac-specific check whether we're in a GUI session (issue2553)
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 13439
diff changeset
   555
            # pure build; use a safe default
16118b4859a1 util: add Mac-specific check whether we're in a GUI session (issue2553)
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 13439
diff changeset
   556
            return True
16118b4859a1 util: add Mac-specific check whether we're in a GUI session (issue2553)
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 13439
diff changeset
   557
    else:
46459
128a17d8436f procutil: extend gui test to detect wayland session (issue6479)
Yuya Nishihara <yuya@tcha.org>
parents: 46175
diff changeset
   558
        return (
128a17d8436f procutil: extend gui test to detect wayland session (issue6479)
Yuya Nishihara <yuya@tcha.org>
parents: 46175
diff changeset
   559
            pycompat.iswindows
128a17d8436f procutil: extend gui test to detect wayland session (issue6479)
Yuya Nishihara <yuya@tcha.org>
parents: 46175
diff changeset
   560
            or encoding.environ.get(b"DISPLAY")
128a17d8436f procutil: extend gui test to detect wayland session (issue6479)
Yuya Nishihara <yuya@tcha.org>
parents: 46175
diff changeset
   561
            or encoding.environ.get(b"WAYLAND_DISPLAY")
128a17d8436f procutil: extend gui test to detect wayland session (issue6479)
Yuya Nishihara <yuya@tcha.org>
parents: 46175
diff changeset
   562
        )
6007
090b1a665901 filemerge: add config item for GUI tools
Matt Mackall <mpm@selenic.com>
parents: 6006
diff changeset
   563
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   564
43912
a89381e04c58 procutil: try and avoid angering CoreFoundation on macOS
Augie Fackler <augie@google.com>
parents: 43862
diff changeset
   565
def gui():
a89381e04c58 procutil: try and avoid angering CoreFoundation on macOS
Augie Fackler <augie@google.com>
parents: 43862
diff changeset
   566
    global _is_gui
a89381e04c58 procutil: try and avoid angering CoreFoundation on macOS
Augie Fackler <augie@google.com>
parents: 43862
diff changeset
   567
    if _is_gui is None:
a89381e04c58 procutil: try and avoid angering CoreFoundation on macOS
Augie Fackler <augie@google.com>
parents: 43862
diff changeset
   568
        _is_gui = _gui()
a89381e04c58 procutil: try and avoid angering CoreFoundation on macOS
Augie Fackler <augie@google.com>
parents: 43862
diff changeset
   569
    return _is_gui
a89381e04c58 procutil: try and avoid angering CoreFoundation on macOS
Augie Fackler <augie@google.com>
parents: 43862
diff changeset
   570
a89381e04c58 procutil: try and avoid angering CoreFoundation on macOS
Augie Fackler <augie@google.com>
parents: 43862
diff changeset
   571
10239
8e4be44a676f Find right hg command for detached process
Patrick Mezard <pmezard@gmail.com>
parents: 10199
diff changeset
   572
def hgcmd():
8e4be44a676f Find right hg command for detached process
Patrick Mezard <pmezard@gmail.com>
parents: 10199
diff changeset
   573
    """Return the command used to execute current hg
8e4be44a676f Find right hg command for detached process
Patrick Mezard <pmezard@gmail.com>
parents: 10199
diff changeset
   574
8e4be44a676f Find right hg command for detached process
Patrick Mezard <pmezard@gmail.com>
parents: 10199
diff changeset
   575
    This is different from hgexecutable() because on Windows we want
8e4be44a676f Find right hg command for detached process
Patrick Mezard <pmezard@gmail.com>
parents: 10199
diff changeset
   576
    to avoid things opening new shell windows like batch files, so we
8e4be44a676f Find right hg command for detached process
Patrick Mezard <pmezard@gmail.com>
parents: 10199
diff changeset
   577
    get either the python call or current executable.
8e4be44a676f Find right hg command for detached process
Patrick Mezard <pmezard@gmail.com>
parents: 10199
diff changeset
   578
    """
43671
664e24207728 procutil: move mainfrozen() to new resourceutil.py
Martin von Zweigbergk <martinvonz@google.com>
parents: 43657
diff changeset
   579
    if resourceutil.mainfrozen():
43657
38387f9e4d22 py3: use native string for 'macosx_app'
Martin von Zweigbergk <martinvonz@google.com>
parents: 43656
diff changeset
   580
        if getattr(sys, 'frozen', None) == 'macosx_app':
27766
198f78a52a2f util: adjust hgcmd() to handle frozen Mercurial on OS X
Matt Harbison <matt_harbison@yahoo.com>
parents: 27765
diff changeset
   581
            # Env variable set by py2app
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   582
            return [encoding.environ[b'EXECUTABLEPATH']]
27766
198f78a52a2f util: adjust hgcmd() to handle frozen Mercurial on OS X
Matt Harbison <matt_harbison@yahoo.com>
parents: 27765
diff changeset
   583
        else:
30669
10b17ed9b591 py3: replace sys.executable with pycompat.sysexecutable
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30642
diff changeset
   584
            return [pycompat.sysexecutable]
37115
49d6ba67c93f util: mark platform-specific gethgcmd() as private
Yuya Nishihara <yuya@tcha.org>
parents: 37099
diff changeset
   585
    return _gethgcmd()
10344
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   586
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   587
10344
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   588
def rundetached(args, condfn):
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   589
    """Execute the argument list in a detached process.
10422
600142e7a028 util: fix trailing whitespace found by check-code
Augie Fackler <durin42@gmail.com>
parents: 10344
diff changeset
   590
10344
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   591
    condfn is a callable which is called repeatedly and should return
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   592
    True once the child process is known to have started successfully.
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   593
    At this point, the child process PID is returned. If the child
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   594
    process fails to start or finishes before condfn() evaluates to
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   595
    True, return -1.
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   596
    """
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   597
    # Windows case is easier because the child process is either
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   598
    # successfully starting and validating the condition or exiting
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   599
    # on failure. We just poll on its PID. On Unix, if the child
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   600
    # process fails to start, it will be left in a zombie state until
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   601
    # the parent wait on it, which we cannot do since we expect a long
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   602
    # running process on success. Instead we listen for SIGCHLD telling
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   603
    # us our child process terminated.
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   604
    terminated = set()
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   605
10344
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   606
    def handler(signum, frame):
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   607
        terminated.add(os.wait())
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   608
10344
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   609
    prevhandler = None
14968
b7dbe957585c util: use safehasattr or getattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents: 14942
diff changeset
   610
    SIGCHLD = getattr(signal, 'SIGCHLD', None)
b7dbe957585c util: use safehasattr or getattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents: 14942
diff changeset
   611
    if SIGCHLD is not None:
b7dbe957585c util: use safehasattr or getattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents: 14942
diff changeset
   612
        prevhandler = signal.signal(SIGCHLD, handler)
10344
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   613
    try:
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   614
        pid = spawndetached(args)
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   615
        while not condfn():
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   616
            if (pid in terminated or not testpid(pid)) and not condfn():
10344
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   617
                return -1
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   618
            time.sleep(0.1)
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   619
        return pid
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   620
    finally:
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   621
        if prevhandler is not None:
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   622
            signal.signal(signal.SIGCHLD, prevhandler)
38526
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   623
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   624
38526
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   625
@contextlib.contextmanager
41076
8ecb17b7f432 procutil: correct spelling of uninterruptable -> uninterruptible
Kyle Lippincott <spectral@google.com>
parents: 40712
diff changeset
   626
def uninterruptible(warn):
38526
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   627
    """Inhibit SIGINT handling on a region of code.
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   628
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   629
    Note that if this is called in a non-main thread, it turns into a no-op.
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   630
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   631
    Args:
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   632
      warn: A callable which takes no arguments, and returns True if the
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   633
            previous signal handling should be restored.
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   634
    """
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   635
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   636
    oldsiginthandler = [signal.getsignal(signal.SIGINT)]
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   637
    shouldbail = []
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   638
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   639
    def disabledsiginthandler(*args):
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   640
        if warn():
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   641
            signal.signal(signal.SIGINT, oldsiginthandler[0])
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   642
            del oldsiginthandler[0]
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   643
        shouldbail.append(True)
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   644
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   645
    try:
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   646
        try:
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   647
            signal.signal(signal.SIGINT, disabledsiginthandler)
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   648
        except ValueError:
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   649
            # wrong thread, oh well, we tried
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   650
            del oldsiginthandler[0]
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   651
        yield
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   652
    finally:
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   653
        if oldsiginthandler:
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   654
            signal.signal(signal.SIGINT, oldsiginthandler[0])
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   655
        if shouldbail:
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   656
            raise KeyboardInterrupt
40497
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   657
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   658
40497
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   659
if pycompat.iswindows:
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   660
    # no fork on Windows, but we can create a detached process
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   661
    # https://msdn.microsoft.com/en-us/library/windows/desktop/ms684863.aspx
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   662
    # No stdlib constant exists for this value
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   663
    DETACHED_PROCESS = 0x00000008
40536
1d3bed7d2923 procutil: import concerns about creationflags on Windows from D1701
Boris Feld <boris.feld@octobus.net>
parents: 40498
diff changeset
   664
    # Following creation flags might create a console GUI window.
1d3bed7d2923 procutil: import concerns about creationflags on Windows from D1701
Boris Feld <boris.feld@octobus.net>
parents: 40498
diff changeset
   665
    # Using subprocess.CREATE_NEW_CONSOLE might helps.
1d3bed7d2923 procutil: import concerns about creationflags on Windows from D1701
Boris Feld <boris.feld@octobus.net>
parents: 40498
diff changeset
   666
    # See https://phab.mercurial-scm.org/D1701 for discussion
43478
54f4d094bab1 procutil: suppress pytype warnings around windows-only attributes
Augie Fackler <augie@google.com>
parents: 43165
diff changeset
   667
    _creationflags = (
54f4d094bab1 procutil: suppress pytype warnings around windows-only attributes
Augie Fackler <augie@google.com>
parents: 43165
diff changeset
   668
        DETACHED_PROCESS
54f4d094bab1 procutil: suppress pytype warnings around windows-only attributes
Augie Fackler <augie@google.com>
parents: 43165
diff changeset
   669
        | subprocess.CREATE_NEW_PROCESS_GROUP  # pytype: disable=module-attr
54f4d094bab1 procutil: suppress pytype warnings around windows-only attributes
Augie Fackler <augie@google.com>
parents: 43165
diff changeset
   670
    )
40497
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   671
42496
ca1014ad3de4 procutil: allow callers of runbgcommand to assume the process starts
Augie Fackler <augie@google.com>
parents: 41832
diff changeset
   672
    def runbgcommand(
43848
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   673
        script,
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   674
        env,
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   675
        shell=False,
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   676
        stdout=None,
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   677
        stderr=None,
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   678
        ensurestart=True,
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   679
        record_wait=None,
45786
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
   680
        stdin_bytes=None,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   681
    ):
40497
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   682
        '''Spawn a command without waiting for it to finish.'''
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   683
        # we can't use close_fds *and* redirect stdin. I'm not sure that we
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   684
        # need to because the detached process has no console connection.
45786
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
   685
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
   686
        try:
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
   687
            stdin = None
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
   688
            if stdin_bytes is not None:
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
   689
                stdin = pycompat.unnamedtempfile()
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
   690
                stdin.write(stdin_bytes)
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
   691
                stdin.flush()
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
   692
                stdin.seek(0)
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
   693
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
   694
            p = subprocess.Popen(
46030
2cf61e66c6d0 merge with stable
Augie Fackler <augie@google.com>
parents: 45942 46019
diff changeset
   695
                pycompat.rapply(tonativestr, script),
45786
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
   696
                shell=shell,
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
   697
                env=tonativeenv(env),
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
   698
                close_fds=True,
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
   699
                creationflags=_creationflags,
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
   700
                stdin=stdin,
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
   701
                stdout=stdout,
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
   702
                stderr=stderr,
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
   703
            )
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
   704
            if record_wait is not None:
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
   705
                record_wait(p.wait)
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
   706
        finally:
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
   707
            if stdin is not None:
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
   708
                stdin.close()
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   709
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   710
40497
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   711
else:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   712
48910
3681b4c56618 procutil: delete Python 2 support code
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48875
diff changeset
   713
    def runbgcommand(
46889
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   714
        cmd,
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   715
        env,
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   716
        shell=False,
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   717
        stdout=None,
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   718
        stderr=None,
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   719
        ensurestart=True,
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   720
        record_wait=None,
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   721
        stdin_bytes=None,
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   722
    ):
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   723
        """Spawn a command without waiting for it to finish.
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   724
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   725
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   726
        When `record_wait` is not None, the spawned process will not be fully
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   727
        detached and the `record_wait` argument will be called with a the
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   728
        `Subprocess.wait` function for the spawned process.  This is mostly
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   729
        useful for developers that need to make sure the spawned process
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   730
        finished before a certain point. (eg: writing test)"""
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   731
        if pycompat.isdarwin:
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   732
            # avoid crash in CoreFoundation in case another thread
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   733
            # calls gui() while we're calling fork().
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   734
            gui()
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   735
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   736
        if shell:
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   737
            script = cmd
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   738
        else:
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   739
            if isinstance(cmd, bytes):
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   740
                cmd = [cmd]
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   741
            script = b' '.join(shellquote(x) for x in cmd)
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   742
        if record_wait is None:
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   743
            # double-fork to completely detach from the parent process
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   744
            script = b'( %s ) &' % script
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   745
            start_new_session = True
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   746
        else:
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   747
            start_new_session = False
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   748
            ensurestart = True
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   749
48488
f8540fe4be0f procutil: avoid an uninitialized variable usage on tempfile exception
Matt Harbison <matt_harbison@yahoo.com>
parents: 48487
diff changeset
   750
        stdin = None
f8540fe4be0f procutil: avoid an uninitialized variable usage on tempfile exception
Matt Harbison <matt_harbison@yahoo.com>
parents: 48487
diff changeset
   751
46889
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   752
        try:
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   753
            if stdin_bytes is None:
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   754
                stdin = subprocess.DEVNULL
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   755
            else:
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   756
                stdin = pycompat.unnamedtempfile()
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   757
                stdin.write(stdin_bytes)
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   758
                stdin.flush()
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   759
                stdin.seek(0)
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   760
            if stdout is None:
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   761
                stdout = subprocess.DEVNULL
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   762
            if stderr is None:
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   763
                stderr = subprocess.DEVNULL
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   764
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   765
            p = subprocess.Popen(
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   766
                script,
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   767
                shell=True,
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   768
                env=env,
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   769
                close_fds=True,
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   770
                stdin=stdin,
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   771
                stdout=stdout,
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   772
                stderr=stderr,
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   773
                start_new_session=start_new_session,
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   774
            )
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   775
        except Exception:
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   776
            if record_wait is not None:
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   777
                record_wait(255)
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   778
            raise
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   779
        finally:
48488
f8540fe4be0f procutil: avoid an uninitialized variable usage on tempfile exception
Matt Harbison <matt_harbison@yahoo.com>
parents: 48487
diff changeset
   780
            if stdin_bytes is not None and stdin is not None:
48487
333a2656e981 pytype: stop excluding procutil.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 46889
diff changeset
   781
                assert not isinstance(stdin, int)
46889
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   782
                stdin.close()
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   783
        if not ensurestart:
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   784
            # Even though we're not waiting on the child process,
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   785
            # we still must call waitpid() on it at some point so
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   786
            # it's not a zombie/defunct. This is especially relevant for
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   787
            # chg since the parent process won't die anytime soon.
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   788
            # We use a thread to make the overhead tiny.
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   789
            t = threading.Thread(target=lambda: p.wait)
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   790
            t.daemon = True
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   791
            t.start()
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   792
        else:
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   793
            returncode = p.wait
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   794
            if record_wait is not None:
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   795
                record_wait(returncode)