mercurial/utils/procutil.py
author Joerg Sonnenberger <joerg@bec.de>
Fri, 30 Apr 2021 02:11:58 +0200
changeset 47043 12450fbea288
parent 46889 8759e22f1649
child 48487 333a2656e981
permissions -rw-r--r--
manifests: push down expected node length into the parser This strictly enforces the node length in the manifest lines according to what the repository expects. One test case moves large hash testing into the non-treemanifest part as treemanifests don't provide an interface for overriding just the node length for now. Differential Revision: https://phab.mercurial-scm.org/D10533
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
37118
5be286db5fb5 procutil: move process/executable management functions to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37117
diff changeset
    10
from __future__ import absolute_import
27358
ac839ee45b6a util: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27357
diff changeset
    11
37124
6715e8035b4f procutil: introduce context-manager interface for protect/restorestdio
Yuya Nishihara <yuya@tcha.org>
parents: 37123
diff changeset
    12
import contextlib
40497
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
    13
import errno
36432
1ca4e86c7265 util: handle fileno() on Python 3 throwing io.UnsupportedOperation
Augie Fackler <augie@google.com>
parents: 36422
diff changeset
    14
import io
27358
ac839ee45b6a util: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27357
diff changeset
    15
import os
ac839ee45b6a util: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27357
diff changeset
    16
import signal
ac839ee45b6a util: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27357
diff changeset
    17
import subprocess
ac839ee45b6a util: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27357
diff changeset
    18
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
    19
import threading
27358
ac839ee45b6a util: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27357
diff changeset
    20
import time
3769
96095d9ff1f8 Add encoding detection
Matt Mackall <mpm@selenic.com>
parents: 3767
diff changeset
    21
37118
5be286db5fb5 procutil: move process/executable management functions to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37117
diff changeset
    22
from ..i18n import _
43089
c59eb1560c44 py3: manually import getattr where it is needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43085
diff changeset
    23
from ..pycompat import (
c59eb1560c44 py3: manually import getattr where it is needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43085
diff changeset
    24
    getattr,
c59eb1560c44 py3: manually import getattr where it is needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43085
diff changeset
    25
    open,
c59eb1560c44 py3: manually import getattr where it is needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43085
diff changeset
    26
)
37118
5be286db5fb5 procutil: move process/executable management functions to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37117
diff changeset
    27
5be286db5fb5 procutil: move process/executable management functions to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37117
diff changeset
    28
from .. import (
27358
ac839ee45b6a util: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27357
diff changeset
    29
    encoding,
ac839ee45b6a util: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27357
diff changeset
    30
    error,
32367
a9c71d578a1c osutil: switch to policy importer
Yuya Nishihara <yuya@tcha.org>
parents: 32306
diff changeset
    31
    policy,
28818
6041fb8f2da8 pycompat: add empty and queue to handle py3 divergence
timeless <timeless@mozdev.org>
parents: 28497
diff changeset
    32
    pycompat,
37083
f99d64e8a4e4 stringutil: move generic string helpers to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37082
diff changeset
    33
)
3769
96095d9ff1f8 Add encoding detection
Matt Mackall <mpm@selenic.com>
parents: 3767
diff changeset
    34
43671
664e24207728 procutil: move mainfrozen() to new resourceutil.py
Martin von Zweigbergk <martinvonz@google.com>
parents: 43657
diff changeset
    35
# 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
    36
from ..utils import resourceutil
664e24207728 procutil: move mainfrozen() to new resourceutil.py
Martin von Zweigbergk <martinvonz@google.com>
parents: 43657
diff changeset
    37
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43503
diff changeset
    38
osutil = policy.importmod('osutil')
32201
4462a981e8df base85: proxy through util module
Yuya Nishihara <yuya@tcha.org>
parents: 32154
diff changeset
    39
45042
c88577199023 procutil: split import and reassignment
Manuel Jacob <me@manueljacob.de>
parents: 45041
diff changeset
    40
if pycompat.iswindows:
c88577199023 procutil: split import and reassignment
Manuel Jacob <me@manueljacob.de>
parents: 45041
diff changeset
    41
    from .. import windows as platform
c88577199023 procutil: split import and reassignment
Manuel Jacob <me@manueljacob.de>
parents: 45041
diff changeset
    42
else:
c88577199023 procutil: split import and reassignment
Manuel Jacob <me@manueljacob.de>
parents: 45041
diff changeset
    43
    from .. import posix as platform
c88577199023 procutil: split import and reassignment
Manuel Jacob <me@manueljacob.de>
parents: 45041
diff changeset
    44
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
    45
30876
3a4c0905f357 util: always force line buffered stdout when stdout is a tty (BC)
Simon Farnsworth <simonfar@fb.com>
parents: 30854
diff changeset
    46
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
    47
    try:
3a4c0905f357 util: always force line buffered stdout when stdout is a tty (BC)
Simon Farnsworth <simonfar@fb.com>
parents: 30854
diff changeset
    48
        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
    49
    except AttributeError:
3a4c0905f357 util: always force line buffered stdout when stdout is a tty (BC)
Simon Farnsworth <simonfar@fb.com>
parents: 30854
diff changeset
    50
        return False
3a4c0905f357 util: always force line buffered stdout when stdout is a tty (BC)
Simon Farnsworth <simonfar@fb.com>
parents: 30854
diff changeset
    51
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
    52
46174
a1601ff3877c procutil: introduce pseudo file object that just raises EBADF
Yuya Nishihara <yuya@tcha.org>
parents: 46102
diff changeset
    53
class BadFile(io.RawIOBase):
a1601ff3877c procutil: introduce pseudo file object that just raises EBADF
Yuya Nishihara <yuya@tcha.org>
parents: 46102
diff changeset
    54
    """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
    55
a1601ff3877c procutil: introduce pseudo file object that just raises EBADF
Yuya Nishihara <yuya@tcha.org>
parents: 46102
diff changeset
    56
    def readinto(self, b):
a1601ff3877c procutil: introduce pseudo file object that just raises EBADF
Yuya Nishihara <yuya@tcha.org>
parents: 46102
diff changeset
    57
        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
    58
a1601ff3877c procutil: introduce pseudo file object that just raises EBADF
Yuya Nishihara <yuya@tcha.org>
parents: 46102
diff changeset
    59
    def write(self, b):
a1601ff3877c procutil: introduce pseudo file object that just raises EBADF
Yuya Nishihara <yuya@tcha.org>
parents: 46102
diff changeset
    60
        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
    61
a1601ff3877c procutil: introduce pseudo file object that just raises EBADF
Yuya Nishihara <yuya@tcha.org>
parents: 46102
diff changeset
    62
45039
2bfbd7d2c204 procutil: define LineBufferedWrapper on all Python versions
Manuel Jacob <me@manueljacob.de>
parents: 45000
diff changeset
    63
class LineBufferedWrapper(object):
2bfbd7d2c204 procutil: define LineBufferedWrapper on all Python versions
Manuel Jacob <me@manueljacob.de>
parents: 45000
diff changeset
    64
    def __init__(self, orig):
2bfbd7d2c204 procutil: define LineBufferedWrapper on all Python versions
Manuel Jacob <me@manueljacob.de>
parents: 45000
diff changeset
    65
        self.orig = orig
44950
f9734b2d59cc py3: make stdout line-buffered if connected to a TTY
Manuel Jacob <me@manueljacob.de>
parents: 44867
diff changeset
    66
45039
2bfbd7d2c204 procutil: define LineBufferedWrapper on all Python versions
Manuel Jacob <me@manueljacob.de>
parents: 45000
diff changeset
    67
    def __getattr__(self, attr):
2bfbd7d2c204 procutil: define LineBufferedWrapper on all Python versions
Manuel Jacob <me@manueljacob.de>
parents: 45000
diff changeset
    68
        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
    69
45039
2bfbd7d2c204 procutil: define LineBufferedWrapper on all Python versions
Manuel Jacob <me@manueljacob.de>
parents: 45000
diff changeset
    70
    def write(self, s):
2bfbd7d2c204 procutil: define LineBufferedWrapper on all Python versions
Manuel Jacob <me@manueljacob.de>
parents: 45000
diff changeset
    71
        orig = self.orig
2bfbd7d2c204 procutil: define LineBufferedWrapper on all Python versions
Manuel Jacob <me@manueljacob.de>
parents: 45000
diff changeset
    72
        res = orig.write(s)
2bfbd7d2c204 procutil: define LineBufferedWrapper on all Python versions
Manuel Jacob <me@manueljacob.de>
parents: 45000
diff changeset
    73
        if s.endswith(b'\n'):
2bfbd7d2c204 procutil: define LineBufferedWrapper on all Python versions
Manuel Jacob <me@manueljacob.de>
parents: 45000
diff changeset
    74
            orig.flush()
2bfbd7d2c204 procutil: define LineBufferedWrapper on all Python versions
Manuel Jacob <me@manueljacob.de>
parents: 45000
diff changeset
    75
        return res
44950
f9734b2d59cc py3: make stdout line-buffered if connected to a TTY
Manuel Jacob <me@manueljacob.de>
parents: 44867
diff changeset
    76
45039
2bfbd7d2c204 procutil: define LineBufferedWrapper on all Python versions
Manuel Jacob <me@manueljacob.de>
parents: 45000
diff changeset
    77
2bfbd7d2c204 procutil: define LineBufferedWrapper on all Python versions
Manuel Jacob <me@manueljacob.de>
parents: 45000
diff changeset
    78
io.BufferedIOBase.register(LineBufferedWrapper)
44950
f9734b2d59cc py3: make stdout line-buffered if connected to a TTY
Manuel Jacob <me@manueljacob.de>
parents: 44867
diff changeset
    79
f9734b2d59cc py3: make stdout line-buffered if connected to a TTY
Manuel Jacob <me@manueljacob.de>
parents: 44867
diff changeset
    80
45040
fd205a9c358a procutil: factor out conditional creation of LineBufferedWrapper
Manuel Jacob <me@manueljacob.de>
parents: 45039
diff changeset
    81
def make_line_buffered(stream):
fd205a9c358a procutil: factor out conditional creation of LineBufferedWrapper
Manuel Jacob <me@manueljacob.de>
parents: 45039
diff changeset
    82
    if pycompat.ispy3 and not isinstance(stream, io.BufferedIOBase):
fd205a9c358a procutil: factor out conditional creation of LineBufferedWrapper
Manuel Jacob <me@manueljacob.de>
parents: 45039
diff changeset
    83
        # On Python 3, buffered streams can be expected to subclass
fd205a9c358a procutil: factor out conditional creation of LineBufferedWrapper
Manuel Jacob <me@manueljacob.de>
parents: 45039
diff changeset
    84
        # BufferedIOBase. This is definitively the case for the streams
fd205a9c358a procutil: factor out conditional creation of LineBufferedWrapper
Manuel Jacob <me@manueljacob.de>
parents: 45039
diff changeset
    85
        # initialized by the interpreter. For unbuffered streams, we don't need
fd205a9c358a procutil: factor out conditional creation of LineBufferedWrapper
Manuel Jacob <me@manueljacob.de>
parents: 45039
diff changeset
    86
        # to emulate line buffering.
fd205a9c358a procutil: factor out conditional creation of LineBufferedWrapper
Manuel Jacob <me@manueljacob.de>
parents: 45039
diff changeset
    87
        return stream
fd205a9c358a procutil: factor out conditional creation of LineBufferedWrapper
Manuel Jacob <me@manueljacob.de>
parents: 45039
diff changeset
    88
    if isinstance(stream, LineBufferedWrapper):
fd205a9c358a procutil: factor out conditional creation of LineBufferedWrapper
Manuel Jacob <me@manueljacob.de>
parents: 45039
diff changeset
    89
        return stream
fd205a9c358a procutil: factor out conditional creation of LineBufferedWrapper
Manuel Jacob <me@manueljacob.de>
parents: 45039
diff changeset
    90
    return LineBufferedWrapper(stream)
fd205a9c358a procutil: factor out conditional creation of LineBufferedWrapper
Manuel Jacob <me@manueljacob.de>
parents: 45039
diff changeset
    91
fd205a9c358a procutil: factor out conditional creation of LineBufferedWrapper
Manuel Jacob <me@manueljacob.de>
parents: 45039
diff changeset
    92
45852
b56feaa9b520 chgserver: backport py3 buffered I/O workarounds from procutil
Yuya Nishihara <yuya@tcha.org>
parents: 45786
diff changeset
    93
def unwrap_line_buffered(stream):
b56feaa9b520 chgserver: backport py3 buffered I/O workarounds from procutil
Yuya Nishihara <yuya@tcha.org>
parents: 45786
diff changeset
    94
    if isinstance(stream, LineBufferedWrapper):
b56feaa9b520 chgserver: backport py3 buffered I/O workarounds from procutil
Yuya Nishihara <yuya@tcha.org>
parents: 45786
diff changeset
    95
        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
    96
        return stream.orig
b56feaa9b520 chgserver: backport py3 buffered I/O workarounds from procutil
Yuya Nishihara <yuya@tcha.org>
parents: 45786
diff changeset
    97
    return stream
b56feaa9b520 chgserver: backport py3 buffered I/O workarounds from procutil
Yuya Nishihara <yuya@tcha.org>
parents: 45786
diff changeset
    98
b56feaa9b520 chgserver: backport py3 buffered I/O workarounds from procutil
Yuya Nishihara <yuya@tcha.org>
parents: 45786
diff changeset
    99
45095
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
   100
class WriteAllWrapper(object):
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
   101
    def __init__(self, orig):
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
   102
        self.orig = orig
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
   103
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
   104
    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
   105
        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
   106
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
   107
    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
   108
        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
   109
        m = memoryview(s)
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
   110
        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
   111
        total_written = 0
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
   112
        while total_written < total_to_write:
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
   113
            total_written += write1(m[total_written:])
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
   114
        return total_written
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
   115
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
   116
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
   117
io.IOBase.register(WriteAllWrapper)
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
   118
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
   119
45103
a5fa2761a6cd procutil: make _make_write_all() function private
Manuel Jacob <me@manueljacob.de>
parents: 45095
diff changeset
   120
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
   121
    assert pycompat.ispy3
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
   122
    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
   123
        return stream
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
   124
    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
   125
        # 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
   126
        # written.
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
   127
        return stream
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
   128
    # 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
   129
    # the data.
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
   130
    return WriteAllWrapper(stream)
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
   131
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
   132
45056
9694895749ad pycompat: remove pycompat.{stdin,stdout,stderr}
Manuel Jacob <me@manueljacob.de>
parents: 45045
diff changeset
   133
if pycompat.ispy3:
46175
a04c03b0678e procutil: assign pseudo file object if sys.stdout/stderr is missing
Yuya Nishihara <yuya@tcha.org>
parents: 46174
diff changeset
   134
    # Python 3 implements its own I/O streams. Unlike stdio of C library,
a04c03b0678e procutil: assign pseudo file object if sys.stdout/stderr is missing
Yuya Nishihara <yuya@tcha.org>
parents: 46174
diff changeset
   135
    # sys.stdin/stdout/stderr may be None if underlying fd is closed.
a04c03b0678e procutil: assign pseudo file object if sys.stdout/stderr is missing
Yuya Nishihara <yuya@tcha.org>
parents: 46174
diff changeset
   136
45056
9694895749ad pycompat: remove pycompat.{stdin,stdout,stderr}
Manuel Jacob <me@manueljacob.de>
parents: 45045
diff changeset
   137
    # TODO: .buffer might not exist if std streams were replaced; we'll need
9694895749ad pycompat: remove pycompat.{stdin,stdout,stderr}
Manuel Jacob <me@manueljacob.de>
parents: 45045
diff changeset
   138
    # a silly wrapper to make a bytes stream backed by a unicode one.
46083
81c1f5d1801f procutils: don't try to get `.buffer` if sys.stdin is None
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46030
diff changeset
   139
46175
a04c03b0678e procutil: assign pseudo file object if sys.stdout/stderr is missing
Yuya Nishihara <yuya@tcha.org>
parents: 46174
diff changeset
   140
    if sys.stdin is None:
a04c03b0678e procutil: assign pseudo file object if sys.stdout/stderr is missing
Yuya Nishihara <yuya@tcha.org>
parents: 46174
diff changeset
   141
        stdin = BadFile()
a04c03b0678e procutil: assign pseudo file object if sys.stdout/stderr is missing
Yuya Nishihara <yuya@tcha.org>
parents: 46174
diff changeset
   142
    else:
46102
7ce24d3761e8 procutil: don't assign stdin to None, use os.devnull instead
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46083
diff changeset
   143
        stdin = sys.stdin.buffer
46175
a04c03b0678e procutil: assign pseudo file object if sys.stdout/stderr is missing
Yuya Nishihara <yuya@tcha.org>
parents: 46174
diff changeset
   144
    if sys.stdout is None:
a04c03b0678e procutil: assign pseudo file object if sys.stdout/stderr is missing
Yuya Nishihara <yuya@tcha.org>
parents: 46174
diff changeset
   145
        stdout = BadFile()
46102
7ce24d3761e8 procutil: don't assign stdin to None, use os.devnull instead
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46083
diff changeset
   146
    else:
46175
a04c03b0678e procutil: assign pseudo file object if sys.stdout/stderr is missing
Yuya Nishihara <yuya@tcha.org>
parents: 46174
diff changeset
   147
        stdout = _make_write_all(sys.stdout.buffer)
a04c03b0678e procutil: assign pseudo file object if sys.stdout/stderr is missing
Yuya Nishihara <yuya@tcha.org>
parents: 46174
diff changeset
   148
    if sys.stderr is None:
a04c03b0678e procutil: assign pseudo file object if sys.stdout/stderr is missing
Yuya Nishihara <yuya@tcha.org>
parents: 46174
diff changeset
   149
        stderr = BadFile()
a04c03b0678e procutil: assign pseudo file object if sys.stdout/stderr is missing
Yuya Nishihara <yuya@tcha.org>
parents: 46174
diff changeset
   150
    else:
a04c03b0678e procutil: assign pseudo file object if sys.stdout/stderr is missing
Yuya Nishihara <yuya@tcha.org>
parents: 46174
diff changeset
   151
        stderr = _make_write_all(sys.stderr.buffer)
a04c03b0678e procutil: assign pseudo file object if sys.stdout/stderr is missing
Yuya Nishihara <yuya@tcha.org>
parents: 46174
diff changeset
   152
45148
a37f290a7124 windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents: 45103
diff changeset
   153
    if pycompat.iswindows:
a37f290a7124 windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents: 45103
diff changeset
   154
        # Work around Windows bugs.
46784
65f437c240f2 typing: disable a few errors when accessing Windows specific attributes
Matt Harbison <matt_harbison@yahoo.com>
parents: 46459
diff changeset
   155
        stdout = platform.winstdout(stdout)  # pytype: disable=module-attr
65f437c240f2 typing: disable a few errors when accessing Windows specific attributes
Matt Harbison <matt_harbison@yahoo.com>
parents: 46459
diff changeset
   156
        stderr = platform.winstdout(stderr)  # pytype: disable=module-attr
45093
63196198dbf0 procutil: distribute code for stdout
Manuel Jacob <me@manueljacob.de>
parents: 45082
diff changeset
   157
    if isatty(stdout):
63196198dbf0 procutil: distribute code for stdout
Manuel Jacob <me@manueljacob.de>
parents: 45082
diff changeset
   158
        # The standard library doesn't offer line-buffered binary streams.
63196198dbf0 procutil: distribute code for stdout
Manuel Jacob <me@manueljacob.de>
parents: 45082
diff changeset
   159
        stdout = make_line_buffered(stdout)
45056
9694895749ad pycompat: remove pycompat.{stdin,stdout,stderr}
Manuel Jacob <me@manueljacob.de>
parents: 45045
diff changeset
   160
else:
45093
63196198dbf0 procutil: distribute code for stdout
Manuel Jacob <me@manueljacob.de>
parents: 45082
diff changeset
   161
    # Python 2 uses the I/O streams provided by the C library.
45056
9694895749ad pycompat: remove pycompat.{stdin,stdout,stderr}
Manuel Jacob <me@manueljacob.de>
parents: 45045
diff changeset
   162
    stdin = sys.stdin
9694895749ad pycompat: remove pycompat.{stdin,stdout,stderr}
Manuel Jacob <me@manueljacob.de>
parents: 45045
diff changeset
   163
    stdout = sys.stdout
45148
a37f290a7124 windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents: 45103
diff changeset
   164
    stderr = sys.stderr
a37f290a7124 windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents: 45103
diff changeset
   165
    if pycompat.iswindows:
a37f290a7124 windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents: 45103
diff changeset
   166
        # Work around Windows bugs.
46784
65f437c240f2 typing: disable a few errors when accessing Windows specific attributes
Matt Harbison <matt_harbison@yahoo.com>
parents: 46459
diff changeset
   167
        stdout = platform.winstdout(stdout)  # pytype: disable=module-attr
65f437c240f2 typing: disable a few errors when accessing Windows specific attributes
Matt Harbison <matt_harbison@yahoo.com>
parents: 46459
diff changeset
   168
        stderr = platform.winstdout(stderr)  # pytype: disable=module-attr
45093
63196198dbf0 procutil: distribute code for stdout
Manuel Jacob <me@manueljacob.de>
parents: 45082
diff changeset
   169
    if isatty(stdout):
63196198dbf0 procutil: distribute code for stdout
Manuel Jacob <me@manueljacob.de>
parents: 45082
diff changeset
   170
        if pycompat.iswindows:
63196198dbf0 procutil: distribute code for stdout
Manuel Jacob <me@manueljacob.de>
parents: 45082
diff changeset
   171
            # The Windows C runtime library doesn't support line buffering.
63196198dbf0 procutil: distribute code for stdout
Manuel Jacob <me@manueljacob.de>
parents: 45082
diff changeset
   172
            stdout = make_line_buffered(stdout)
63196198dbf0 procutil: distribute code for stdout
Manuel Jacob <me@manueljacob.de>
parents: 45082
diff changeset
   173
        else:
63196198dbf0 procutil: distribute code for stdout
Manuel Jacob <me@manueljacob.de>
parents: 45082
diff changeset
   174
            # glibc determines buffering on first write to stdout - if we
63196198dbf0 procutil: distribute code for stdout
Manuel Jacob <me@manueljacob.de>
parents: 45082
diff changeset
   175
            # replace a TTY destined stdout with a pipe destined stdout (e.g.
63196198dbf0 procutil: distribute code for stdout
Manuel Jacob <me@manueljacob.de>
parents: 45082
diff changeset
   176
            # pager), we want line buffering.
63196198dbf0 procutil: distribute code for stdout
Manuel Jacob <me@manueljacob.de>
parents: 45082
diff changeset
   177
            stdout = os.fdopen(stdout.fileno(), 'wb', 1)
30876
3a4c0905f357 util: always force line buffered stdout when stdout is a tty (BC)
Simon Farnsworth <simonfar@fb.com>
parents: 30854
diff changeset
   178
14926
4e7e63fc685a util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents: 14918
diff changeset
   179
4e7e63fc685a util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents: 14918
diff changeset
   180
findexe = platform.findexe
37115
49d6ba67c93f util: mark platform-specific gethgcmd() as private
Yuya Nishihara <yuya@tcha.org>
parents: 37099
diff changeset
   181
_gethgcmd = platform.gethgcmd
14926
4e7e63fc685a util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents: 14918
diff changeset
   182
getuser = platform.getuser
28027
14033c5dd261 util: enable getpid to be replaced
timeless <timeless@mozdev.org>
parents: 27785
diff changeset
   183
getpid = os.getpid
14926
4e7e63fc685a util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents: 14918
diff changeset
   184
hidewindow = platform.hidewindow
22245
234e4c24b980 platform: implement readpipe()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21914
diff changeset
   185
readpipe = platform.readpipe
14926
4e7e63fc685a util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents: 14918
diff changeset
   186
setbinary = platform.setbinary
4e7e63fc685a util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents: 14918
diff changeset
   187
setsignalhandler = platform.setsignalhandler
4e7e63fc685a util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents: 14918
diff changeset
   188
shellquote = platform.shellquote
36415
0cb09c322647 util: factor out shellsplit() function
Yuya Nishihara <yuya@tcha.org>
parents: 36362
diff changeset
   189
shellsplit = platform.shellsplit
14926
4e7e63fc685a util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents: 14918
diff changeset
   190
spawndetached = platform.spawndetached
4e7e63fc685a util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents: 14918
diff changeset
   191
sshargs = platform.sshargs
4e7e63fc685a util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents: 14918
diff changeset
   192
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
   193
32208
d74b0cff94a9 osutil: proxy through util (and platform) modules (API)
Yuya Nishihara <yuya@tcha.org>
parents: 32201
diff changeset
   194
try:
d74b0cff94a9 osutil: proxy through util (and platform) modules (API)
Yuya Nishihara <yuya@tcha.org>
parents: 32201
diff changeset
   195
    setprocname = osutil.setprocname
d74b0cff94a9 osutil: proxy through util (and platform) modules (API)
Yuya Nishihara <yuya@tcha.org>
parents: 32201
diff changeset
   196
except AttributeError:
d74b0cff94a9 osutil: proxy through util (and platform) modules (API)
Yuya Nishihara <yuya@tcha.org>
parents: 32201
diff changeset
   197
    pass
35460
8652ab4046e4 osutil: add a function to unblock signals
Jun Wu <quark@fb.com>
parents: 35145
diff changeset
   198
try:
8652ab4046e4 osutil: add a function to unblock signals
Jun Wu <quark@fb.com>
parents: 35145
diff changeset
   199
    unblocksignal = osutil.unblocksignal
8652ab4046e4 osutil: add a function to unblock signals
Jun Wu <quark@fb.com>
parents: 35145
diff changeset
   200
except AttributeError:
8652ab4046e4 osutil: add a function to unblock signals
Jun Wu <quark@fb.com>
parents: 35145
diff changeset
   201
    pass
32208
d74b0cff94a9 osutil: proxy through util (and platform) modules (API)
Yuya Nishihara <yuya@tcha.org>
parents: 32201
diff changeset
   202
34646
238abf65a8ad codemod: use pycompat.isposix
Jun Wu <quark@fb.com>
parents: 34645
diff changeset
   203
closefds = pycompat.isposix
10197
29e3c4a7699b subrepo: normalize svn output line-endings
Patrick Mezard <pmezard@gmail.com>
parents: 9996
diff changeset
   204
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   205
37460
a6c6b7beb025 procutil: unify platform.explainexit()
Yuya Nishihara <yuya@tcha.org>
parents: 37459
diff changeset
   206
def explainexit(code):
37463
bbd240f81ac5 procutil: make explainexit() simply return a message (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37462
diff changeset
   207
    """return a message describing a subprocess status
37460
a6c6b7beb025 procutil: unify platform.explainexit()
Yuya Nishihara <yuya@tcha.org>
parents: 37459
diff changeset
   208
    (codes from kill are negative - not os.system/wait encoding)"""
a6c6b7beb025 procutil: unify platform.explainexit()
Yuya Nishihara <yuya@tcha.org>
parents: 37459
diff changeset
   209
    if code >= 0:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   210
        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
   211
    return _(b"killed by signal %d") % -code
37460
a6c6b7beb025 procutil: unify platform.explainexit()
Yuya Nishihara <yuya@tcha.org>
parents: 37459
diff changeset
   212
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   213
37459
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   214
class _pfile(object):
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   215
    """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
   216
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   217
    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
   218
        self._proc = proc
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   219
        self._fp = fp
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   220
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   221
    def close(self):
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   222
        # 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
   223
        self._fp.close()
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   224
        return self._proc.wait()
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 __iter__(self):
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   227
        return iter(self._fp)
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   228
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   229
    def __getattr__(self, attr):
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   230
        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
   231
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   232
    def __enter__(self):
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   233
        return self
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 __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
   236
        self.close()
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   237
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   238
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   239
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
   240
    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
   241
        return _popenreader(cmd, bufsize)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   242
    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
   243
        return _popenwriter(cmd, bufsize)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   244
    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
   245
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   246
37459
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   247
def _popenreader(cmd, bufsize):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   248
    p = subprocess.Popen(
44867
8e8fd938ca07 cleanup: eliminate procutil.quotecommand()
Manuel Jacob <me@manueljacob.de>
parents: 44812
diff changeset
   249
        tonativestr(cmd),
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   250
        shell=True,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   251
        bufsize=bufsize,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   252
        close_fds=closefds,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   253
        stdout=subprocess.PIPE,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   254
    )
37459
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   255
    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
   256
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   257
37459
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   258
def _popenwriter(cmd, bufsize):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   259
    p = subprocess.Popen(
44867
8e8fd938ca07 cleanup: eliminate procutil.quotecommand()
Manuel Jacob <me@manueljacob.de>
parents: 44812
diff changeset
   260
        tonativestr(cmd),
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   261
        shell=True,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   262
        bufsize=bufsize,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   263
        close_fds=closefds,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   264
        stdin=subprocess.PIPE,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   265
    )
37459
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   266
    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
   267
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   268
37464
632b92899203 procutil: drop unused 'newlines' option from popen*() (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37463
diff changeset
   269
def popen2(cmd, env=None):
9089
8ec39725d966 util: remove unused bufsize argument
Martin Geisler <mg@lazybytes.net>
parents: 9084
diff changeset
   270
    # 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
   271
    # 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
   272
    # 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
   273
    p = subprocess.Popen(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   274
        tonativestr(cmd),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   275
        shell=True,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   276
        bufsize=-1,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   277
        close_fds=closefds,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   278
        stdin=subprocess.PIPE,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   279
        stdout=subprocess.PIPE,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   280
        env=tonativeenv(env),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   281
    )
8280
0b02d98d44d0 util: always use subprocess
Martin Geisler <mg@lazybytes.net>
parents: 8257
diff changeset
   282
    return p.stdin, p.stdout
10197
29e3c4a7699b subrepo: normalize svn output line-endings
Patrick Mezard <pmezard@gmail.com>
parents: 9996
diff changeset
   283
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   284
37464
632b92899203 procutil: drop unused 'newlines' option from popen*() (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37463
diff changeset
   285
def popen3(cmd, env=None):
632b92899203 procutil: drop unused 'newlines' option from popen*() (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37463
diff changeset
   286
    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
   287
    return stdin, stdout, stderr
9baf4330d88f sshpeer: store subprocess so it cleans up correctly
Durham Goode <durham@fb.com>
parents: 18736
diff changeset
   288
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   289
37464
632b92899203 procutil: drop unused 'newlines' option from popen*() (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37463
diff changeset
   290
def popen4(cmd, env=None, bufsize=-1):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   291
    p = subprocess.Popen(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   292
        tonativestr(cmd),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   293
        shell=True,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   294
        bufsize=bufsize,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   295
        close_fds=closefds,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   296
        stdin=subprocess.PIPE,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   297
        stdout=subprocess.PIPE,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   298
        stderr=subprocess.PIPE,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   299
        env=tonativeenv(env),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   300
    )
18759
9baf4330d88f sshpeer: store subprocess so it cleans up correctly
Durham Goode <durham@fb.com>
parents: 18736
diff changeset
   301
    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
   302
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   303
1293
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   304
def pipefilter(s, cmd):
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   305
    '''filter string S through command CMD, returning its output'''
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   306
    p = subprocess.Popen(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   307
        tonativestr(cmd),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   308
        shell=True,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   309
        close_fds=closefds,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   310
        stdin=subprocess.PIPE,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   311
        stdout=subprocess.PIPE,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   312
    )
8302
d2ad8c066676 util: simplify pipefilter and avoid subprocess race
Martin Geisler <mg@lazybytes.net>
parents: 8299
diff changeset
   313
    pout, perr = p.communicate(s)
d2ad8c066676 util: simplify pipefilter and avoid subprocess race
Martin Geisler <mg@lazybytes.net>
parents: 8299
diff changeset
   314
    return pout
419
28511fc21073 [PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff changeset
   315
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   316
1293
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   317
def tempfilter(s, cmd):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45852
diff changeset
   318
    """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
   319
    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
   320
    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
   321
    the temporary files generated."""
1293
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   322
    inname, outname = None, None
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   323
    try:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   324
        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
   325
        fp = os.fdopen(infd, 'wb')
1293
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   326
        fp.write(s)
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   327
        fp.close()
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   328
        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
   329
        os.close(outfd)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   330
        cmd = cmd.replace(b'INFILE', inname)
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   331
        cmd = cmd.replace(b'OUTFILE', outname)
37461
538353b80676 procutil: fix error message of tempfile filter
Yuya Nishihara <yuya@tcha.org>
parents: 37460
diff changeset
   332
        code = system(cmd)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   333
        if pycompat.sysplatform == b'OpenVMS' and code & 1:
4720
72fb6f10fac1 OpenVMS patches
Jean-Francois PIERONNE <jf.pieronne@laposte.net>
parents: 4708
diff changeset
   334
            code = 0
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
   335
        if code:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   336
            raise error.Abort(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   337
                _(b"command '%s' failed: %s") % (cmd, explainexit(code))
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   338
            )
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   339
        with open(outname, b'rb') as fp:
37117
e7b517809ebc util: stop using readfile() in tempfilter()
Yuya Nishihara <yuya@tcha.org>
parents: 37116
diff changeset
   340
            return fp.read()
1293
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   341
    finally:
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   342
        try:
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
   343
            if inname:
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
   344
                os.unlink(inname)
14004
97ed99d1f419 eliminate various naked except clauses
Idan Kamara <idankk86@gmail.com>
parents: 13985
diff changeset
   345
        except OSError:
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
   346
            pass
1293
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   347
        try:
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
   348
            if outname:
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
   349
                os.unlink(outname)
14004
97ed99d1f419 eliminate various naked except clauses
Idan Kamara <idankk86@gmail.com>
parents: 13985
diff changeset
   350
        except OSError:
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
   351
            pass
1293
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   352
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   353
37116
7ccc9b8aca4c util: mark filtertable as private constant
Yuya Nishihara <yuya@tcha.org>
parents: 37115
diff changeset
   354
_filtertable = {
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   355
    b'tempfile:': tempfilter,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   356
    b'pipe:': pipefilter,
37116
7ccc9b8aca4c util: mark filtertable as private constant
Yuya Nishihara <yuya@tcha.org>
parents: 37115
diff changeset
   357
}
1293
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   358
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   359
1293
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   360
def filter(s, cmd):
43787
be8552f25cab cleanup: fix docstring formatting
Matt Harbison <matt_harbison@yahoo.com>
parents: 43671
diff changeset
   361
    """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
   362
    output"""
43106
d783f945a701 py3: finish porting iteritems() to pycompat and remove source transformer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43096
diff changeset
   363
    for name, fn in pycompat.iteritems(_filtertable):
1293
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   364
        if cmd.startswith(name):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   365
            return fn(s, cmd[len(name) :].lstrip())
1293
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   366
    return pipefilter(s, cmd)
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
22632
db15bb2d6323 util: move _hgexecutable a few lines, closer to where it is used
Mads Kiilerich <madski@unity3d.com>
parents: 22245
diff changeset
   369
_hgexecutable = None
db15bb2d6323 util: move _hgexecutable a few lines, closer to where it is used
Mads Kiilerich <madski@unity3d.com>
parents: 22245
diff changeset
   370
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   371
5062
3d35c8cb5eb4 Simplify/correct finding the hg executable (fixes issue644)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4832
diff changeset
   372
def hgexecutable():
3d35c8cb5eb4 Simplify/correct finding the hg executable (fixes issue644)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4832
diff changeset
   373
    """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
   374
3d35c8cb5eb4 Simplify/correct finding the hg executable (fixes issue644)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4832
diff changeset
   375
    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
   376
    """
3d35c8cb5eb4 Simplify/correct finding the hg executable (fixes issue644)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4832
diff changeset
   377
    if _hgexecutable is None:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   378
        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
   379
        mainmod = sys.modules['__main__']
6500
a3175cd7dbec Tidy code, fix typo
Bryan O'Sullivan <bos@serpentine.com>
parents: 6499
diff changeset
   380
        if hg:
14229
85fd8402cbc4 rename util.set_hgexecutable to _sethgexecutable
Adrian Buehlmann <adrian@cadifra.com>
parents: 14228
diff changeset
   381
            _sethgexecutable(hg)
43671
664e24207728 procutil: move mainfrozen() to new resourceutil.py
Martin von Zweigbergk <martinvonz@google.com>
parents: 43657
diff changeset
   382
        elif resourceutil.mainfrozen():
43657
38387f9e4d22 py3: use native string for 'macosx_app'
Martin von Zweigbergk <martinvonz@google.com>
parents: 43656
diff changeset
   383
            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
   384
                # Env variable set by py2app
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   385
                _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
   386
            else:
30669
10b17ed9b591 py3: replace sys.executable with pycompat.sysexecutable
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30642
diff changeset
   387
                _sethgexecutable(pycompat.sysexecutable)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   388
        elif (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   389
            not pycompat.iswindows
43656
47d983f0af65 py3: drop an unnecessary fsencode() before comparing with constant
Martin von Zweigbergk <martinvonz@google.com>
parents: 43655
diff changeset
   390
            and os.path.basename(getattr(mainmod, '__file__', '')) == 'hg'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   391
        ):
31074
2912b06905dc py3: use pycompat.fsencode() to convert __file__ to bytes
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30988
diff changeset
   392
            _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
   393
        else:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   394
            _sethgexecutable(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   395
                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
   396
            )
5062
3d35c8cb5eb4 Simplify/correct finding the hg executable (fixes issue644)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4832
diff changeset
   397
    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
   398
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   399
14229
85fd8402cbc4 rename util.set_hgexecutable to _sethgexecutable
Adrian Buehlmann <adrian@cadifra.com>
parents: 14228
diff changeset
   400
def _sethgexecutable(path):
5062
3d35c8cb5eb4 Simplify/correct finding the hg executable (fixes issue644)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4832
diff changeset
   401
    """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
   402
    global _hgexecutable
5062
3d35c8cb5eb4 Simplify/correct finding the hg executable (fixes issue644)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4832
diff changeset
   403
    _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
   404
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   405
36793
eca1051e6c22 util: add public isstdin/isstdout() functions
Yuya Nishihara <yuya@tcha.org>
parents: 36791
diff changeset
   406
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
   407
    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
   408
    try:
36793
eca1051e6c22 util: add public isstdin/isstdout() functions
Yuya Nishihara <yuya@tcha.org>
parents: 36791
diff changeset
   409
        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
   410
    except io.UnsupportedOperation:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   411
        return False  # fileno() raised UnsupportedOperation
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   412
26450
1138e1d05207 util.system: compare fileno to see if it needs stdout redirection
Yuya Nishihara <yuya@tcha.org>
parents: 26392
diff changeset
   413
36793
eca1051e6c22 util: add public isstdin/isstdout() functions
Yuya Nishihara <yuya@tcha.org>
parents: 36791
diff changeset
   414
def isstdin(f):
eca1051e6c22 util: add public isstdin/isstdout() functions
Yuya Nishihara <yuya@tcha.org>
parents: 36791
diff changeset
   415
    return _testfileno(f, sys.__stdin__)
eca1051e6c22 util: add public isstdin/isstdout() functions
Yuya Nishihara <yuya@tcha.org>
parents: 36791
diff changeset
   416
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   417
36793
eca1051e6c22 util: add public isstdin/isstdout() functions
Yuya Nishihara <yuya@tcha.org>
parents: 36791
diff changeset
   418
def isstdout(f):
eca1051e6c22 util: add public isstdin/isstdout() functions
Yuya Nishihara <yuya@tcha.org>
parents: 36791
diff changeset
   419
    return _testfileno(f, sys.__stdout__)
eca1051e6c22 util: add public isstdin/isstdout() functions
Yuya Nishihara <yuya@tcha.org>
parents: 36791
diff changeset
   420
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   421
37123
0216232f21ab procutil: move protectio/restoreio from commandserver
Yuya Nishihara <yuya@tcha.org>
parents: 37118
diff changeset
   422
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
   423
    """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
   424
7f78de1c93aa procutil: redirect ui.fout to stderr while stdio is protected
Yuya Nishihara <yuya@tcha.org>
parents: 37219
diff changeset
   425
    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
   426
    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
   427
0216232f21ab procutil: move protectio/restoreio from commandserver
Yuya Nishihara <yuya@tcha.org>
parents: 37118
diff changeset
   428
    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
   429
    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
   430
    "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
   431
    """
0216232f21ab procutil: move protectio/restoreio from commandserver
Yuya Nishihara <yuya@tcha.org>
parents: 37118
diff changeset
   432
    uout.flush()
37219
ac71cbad5da3 procutil: unroll uin/uout loop in protectstdio()
Yuya Nishihara <yuya@tcha.org>
parents: 37124
diff changeset
   433
    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
   434
    if _testfileno(uin, stdin):
37219
ac71cbad5da3 procutil: unroll uin/uout loop in protectstdio()
Yuya Nishihara <yuya@tcha.org>
parents: 37124
diff changeset
   435
        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
   436
        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
   437
        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
   438
        os.close(nullfd)
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43503
diff changeset
   439
        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
   440
    if _testfileno(uout, stdout):
37219
ac71cbad5da3 procutil: unroll uin/uout loop in protectstdio()
Yuya Nishihara <yuya@tcha.org>
parents: 37124
diff changeset
   441
        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
   442
        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
   443
        fout = os.fdopen(newfd, 'wb')
37219
ac71cbad5da3 procutil: unroll uin/uout loop in protectstdio()
Yuya Nishihara <yuya@tcha.org>
parents: 37124
diff changeset
   444
    return fin, fout
37123
0216232f21ab procutil: move protectio/restoreio from commandserver
Yuya Nishihara <yuya@tcha.org>
parents: 37118
diff changeset
   445
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   446
37123
0216232f21ab procutil: move protectio/restoreio from commandserver
Yuya Nishihara <yuya@tcha.org>
parents: 37118
diff changeset
   447
def restorestdio(uin, uout, fin, fout):
0216232f21ab procutil: move protectio/restoreio from commandserver
Yuya Nishihara <yuya@tcha.org>
parents: 37118
diff changeset
   448
    """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
   449
    uout.flush()
0216232f21ab procutil: move protectio/restoreio from commandserver
Yuya Nishihara <yuya@tcha.org>
parents: 37118
diff changeset
   450
    for f, uif in [(fin, uin), (fout, uout)]:
0216232f21ab procutil: move protectio/restoreio from commandserver
Yuya Nishihara <yuya@tcha.org>
parents: 37118
diff changeset
   451
        if f is not uif:
0216232f21ab procutil: move protectio/restoreio from commandserver
Yuya Nishihara <yuya@tcha.org>
parents: 37118
diff changeset
   452
            os.dup2(f.fileno(), uif.fileno())
0216232f21ab procutil: move protectio/restoreio from commandserver
Yuya Nishihara <yuya@tcha.org>
parents: 37118
diff changeset
   453
            f.close()
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
30736
d9e5b0aeeb90 util: extract the logic calculating environment variables
Jun Wu <quark@fb.com>
parents: 30669
diff changeset
   456
def shellenviron(environ=None):
d9e5b0aeeb90 util: extract the logic calculating environment variables
Jun Wu <quark@fb.com>
parents: 30669
diff changeset
   457
    """return environ with optional override, useful for shelling out"""
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   458
30736
d9e5b0aeeb90 util: extract the logic calculating environment variables
Jun Wu <quark@fb.com>
parents: 30669
diff changeset
   459
    def py2shell(val):
43787
be8552f25cab cleanup: fix docstring formatting
Matt Harbison <matt_harbison@yahoo.com>
parents: 43671
diff changeset
   460
        """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
   461
        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
   462
            return b'0'
30736
d9e5b0aeeb90 util: extract the logic calculating environment variables
Jun Wu <quark@fb.com>
parents: 30669
diff changeset
   463
        if val is True:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   464
            return b'1'
36418
d26b0bedfaa4 util: use pycompat.bytestr() instead of str()
Augie Fackler <augie@google.com>
parents: 36415
diff changeset
   465
        return pycompat.bytestr(val)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   466
30736
d9e5b0aeeb90 util: extract the logic calculating environment variables
Jun Wu <quark@fb.com>
parents: 30669
diff changeset
   467
    env = dict(encoding.environ)
d9e5b0aeeb90 util: extract the logic calculating environment variables
Jun Wu <quark@fb.com>
parents: 30669
diff changeset
   468
    if environ:
43106
d783f945a701 py3: finish porting iteritems() to pycompat and remove source transformer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43096
diff changeset
   469
        env.update((k, py2shell(v)) for k, v in pycompat.iteritems(environ))
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   470
    env[b'HG'] = hgexecutable()
30736
d9e5b0aeeb90 util: extract the logic calculating environment variables
Jun Wu <quark@fb.com>
parents: 30669
diff changeset
   471
    return env
d9e5b0aeeb90 util: extract the logic calculating environment variables
Jun Wu <quark@fb.com>
parents: 30669
diff changeset
   472
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   473
38491
72286f9e324f procutil: add a shim for translating shell commands to native commands
Matt Harbison <matt_harbison@yahoo.com>
parents: 38454
diff changeset
   474
if pycompat.iswindows:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   475
38491
72286f9e324f procutil: add a shim for translating shell commands to native commands
Matt Harbison <matt_harbison@yahoo.com>
parents: 38454
diff changeset
   476
    def shelltonative(cmd, env):
43478
54f4d094bab1 procutil: suppress pytype warnings around windows-only attributes
Augie Fackler <augie@google.com>
parents: 43165
diff changeset
   477
        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
   478
            cmd, shellenviron(env)
54f4d094bab1 procutil: suppress pytype warnings around windows-only attributes
Augie Fackler <augie@google.com>
parents: 43165
diff changeset
   479
        )
39662
50f46b771921 py3: partially fix pager spawning on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 38526
diff changeset
   480
50f46b771921 py3: partially fix pager spawning on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 38526
diff changeset
   481
    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
   482
else:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   483
38491
72286f9e324f procutil: add a shim for translating shell commands to native commands
Matt Harbison <matt_harbison@yahoo.com>
parents: 38454
diff changeset
   484
    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
   485
        return cmd
72286f9e324f procutil: add a shim for translating shell commands to native commands
Matt Harbison <matt_harbison@yahoo.com>
parents: 38454
diff changeset
   486
39662
50f46b771921 py3: partially fix pager spawning on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 38526
diff changeset
   487
    tonativestr = pycompat.identity
50f46b771921 py3: partially fix pager spawning on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 38526
diff changeset
   488
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   489
39662
50f46b771921 py3: partially fix pager spawning on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 38526
diff changeset
   490
def tonativeenv(env):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45852
diff changeset
   491
    """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
   492
    return pycompat.rapply(tonativestr, env)
50f46b771921 py3: partially fix pager spawning on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 38526
diff changeset
   493
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   494
31108
3f8f53190d6a chg: deduplicate error handling of ui.system()
Yuya Nishihara <yuya@tcha.org>
parents: 31074
diff changeset
   495
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
   496
    """enhanced shell command execution.
1882
c0320567931f merge util.esystem and util.system.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1880
diff changeset
   497
    run with environment maybe modified, maybe in different dir.
508
42a660abaf75 [PATCH] Harden os.system
mpm@selenic.com
parents: 464
diff changeset
   498
11469
c37f35d7f2f5 http: deliver hook output to client
Maxim Khitrov <mkhitrov@gmail.com>
parents: 11297
diff changeset
   499
    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
   500
    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
   501
    try:
30473
39d13b8c101d py3: bulk replace sys.stdin/out/err by util's
Yuya Nishihara <yuya@tcha.org>
parents: 30472
diff changeset
   502
        stdout.flush()
13439
d724a69309e0 util: flush stdout before calling external processes
Mads Kiilerich <mads@kiilerich.com>
parents: 13400
diff changeset
   503
    except Exception:
d724a69309e0 util: flush stdout before calling external processes
Mads Kiilerich <mads@kiilerich.com>
parents: 13400
diff changeset
   504
        pass
32886
19b0fd4b5570 plan9: drop py26 hacks
Matt Harbison <matt_harbison@yahoo.com>
parents: 32816
diff changeset
   505
    env = shellenviron(environ)
36793
eca1051e6c22 util: add public isstdin/isstdout() functions
Yuya Nishihara <yuya@tcha.org>
parents: 36791
diff changeset
   506
    if out is None or isstdout(out):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   507
        rc = subprocess.call(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   508
            tonativestr(cmd),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   509
            shell=True,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   510
            close_fds=closefds,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   511
            env=tonativeenv(env),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   512
            cwd=pycompat.rapply(tonativestr, cwd),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   513
        )
11469
c37f35d7f2f5 http: deliver hook output to client
Maxim Khitrov <mkhitrov@gmail.com>
parents: 11297
diff changeset
   514
    else:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   515
        proc = subprocess.Popen(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   516
            tonativestr(cmd),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   517
            shell=True,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   518
            close_fds=closefds,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   519
            env=tonativeenv(env),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   520
            cwd=pycompat.rapply(tonativestr, cwd),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   521
            stdout=subprocess.PIPE,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   522
            stderr=subprocess.STDOUT,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   523
        )
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   524
        for line in iter(proc.stdout.readline, b''):
32886
19b0fd4b5570 plan9: drop py26 hacks
Matt Harbison <matt_harbison@yahoo.com>
parents: 32816
diff changeset
   525
            out.write(line)
19b0fd4b5570 plan9: drop py26 hacks
Matt Harbison <matt_harbison@yahoo.com>
parents: 32816
diff changeset
   526
        proc.wait()
19b0fd4b5570 plan9: drop py26 hacks
Matt Harbison <matt_harbison@yahoo.com>
parents: 32816
diff changeset
   527
        rc = proc.returncode
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   528
    if pycompat.sysplatform == b'OpenVMS' and rc & 1:
32886
19b0fd4b5570 plan9: drop py26 hacks
Matt Harbison <matt_harbison@yahoo.com>
parents: 32816
diff changeset
   529
        rc = 0
9517
4368f582c806 util.system: Use subprocess instead of os.system
Mads Kiilerich <mads@kiilerich.com>
parents: 9508
diff changeset
   530
    return rc
1880
05c7d75be925 fix broken environment save/restore when a hook runs.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1877
diff changeset
   531
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   532
43912
a89381e04c58 procutil: try and avoid angering CoreFoundation on macOS
Augie Fackler <augie@google.com>
parents: 43862
diff changeset
   533
_is_gui = None
a89381e04c58 procutil: try and avoid angering CoreFoundation on macOS
Augie Fackler <augie@google.com>
parents: 43862
diff changeset
   534
a89381e04c58 procutil: try and avoid angering CoreFoundation on macOS
Augie Fackler <augie@google.com>
parents: 43862
diff changeset
   535
a89381e04c58 procutil: try and avoid angering CoreFoundation on macOS
Augie Fackler <augie@google.com>
parents: 43862
diff changeset
   536
def _gui():
6007
090b1a665901 filemerge: add config item for GUI tools
Matt Mackall <mpm@selenic.com>
parents: 6006
diff changeset
   537
    '''Are we running in a GUI?'''
34647
dacfcdd8b94e codemod: use pycompat.isdarwin
Jun Wu <quark@fb.com>
parents: 34646
diff changeset
   538
    if pycompat.isdarwin:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   539
        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
   540
            # 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
   541
            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
   542
        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
   543
            # 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
   544
            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
   545
        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
   546
            # 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
   547
            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
   548
    else:
46459
128a17d8436f procutil: extend gui test to detect wayland session (issue6479)
Yuya Nishihara <yuya@tcha.org>
parents: 46175
diff changeset
   549
        return (
128a17d8436f procutil: extend gui test to detect wayland session (issue6479)
Yuya Nishihara <yuya@tcha.org>
parents: 46175
diff changeset
   550
            pycompat.iswindows
128a17d8436f procutil: extend gui test to detect wayland session (issue6479)
Yuya Nishihara <yuya@tcha.org>
parents: 46175
diff changeset
   551
            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
   552
            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
   553
        )
6007
090b1a665901 filemerge: add config item for GUI tools
Matt Mackall <mpm@selenic.com>
parents: 6006
diff changeset
   554
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   555
43912
a89381e04c58 procutil: try and avoid angering CoreFoundation on macOS
Augie Fackler <augie@google.com>
parents: 43862
diff changeset
   556
def gui():
a89381e04c58 procutil: try and avoid angering CoreFoundation on macOS
Augie Fackler <augie@google.com>
parents: 43862
diff changeset
   557
    global _is_gui
a89381e04c58 procutil: try and avoid angering CoreFoundation on macOS
Augie Fackler <augie@google.com>
parents: 43862
diff changeset
   558
    if _is_gui is None:
a89381e04c58 procutil: try and avoid angering CoreFoundation on macOS
Augie Fackler <augie@google.com>
parents: 43862
diff changeset
   559
        _is_gui = _gui()
a89381e04c58 procutil: try and avoid angering CoreFoundation on macOS
Augie Fackler <augie@google.com>
parents: 43862
diff changeset
   560
    return _is_gui
a89381e04c58 procutil: try and avoid angering CoreFoundation on macOS
Augie Fackler <augie@google.com>
parents: 43862
diff changeset
   561
a89381e04c58 procutil: try and avoid angering CoreFoundation on macOS
Augie Fackler <augie@google.com>
parents: 43862
diff changeset
   562
10239
8e4be44a676f Find right hg command for detached process
Patrick Mezard <pmezard@gmail.com>
parents: 10199
diff changeset
   563
def hgcmd():
8e4be44a676f Find right hg command for detached process
Patrick Mezard <pmezard@gmail.com>
parents: 10199
diff changeset
   564
    """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
   565
8e4be44a676f Find right hg command for detached process
Patrick Mezard <pmezard@gmail.com>
parents: 10199
diff changeset
   566
    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
   567
    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
   568
    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
   569
    """
43671
664e24207728 procutil: move mainfrozen() to new resourceutil.py
Martin von Zweigbergk <martinvonz@google.com>
parents: 43657
diff changeset
   570
    if resourceutil.mainfrozen():
43657
38387f9e4d22 py3: use native string for 'macosx_app'
Martin von Zweigbergk <martinvonz@google.com>
parents: 43656
diff changeset
   571
        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
   572
            # Env variable set by py2app
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   573
            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
   574
        else:
30669
10b17ed9b591 py3: replace sys.executable with pycompat.sysexecutable
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30642
diff changeset
   575
            return [pycompat.sysexecutable]
37115
49d6ba67c93f util: mark platform-specific gethgcmd() as private
Yuya Nishihara <yuya@tcha.org>
parents: 37099
diff changeset
   576
    return _gethgcmd()
10344
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   577
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   578
10344
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   579
def rundetached(args, condfn):
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   580
    """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
   581
10344
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   582
    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
   583
    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
   584
    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
   585
    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
   586
    True, return -1.
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   587
    """
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   588
    # 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
   589
    # 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
   590
    # 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
   591
    # 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
   592
    # 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
   593
    # 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
   594
    # us our child process terminated.
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   595
    terminated = set()
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   596
10344
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   597
    def handler(signum, frame):
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   598
        terminated.add(os.wait())
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   599
10344
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   600
    prevhandler = None
14968
b7dbe957585c util: use safehasattr or getattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents: 14942
diff changeset
   601
    SIGCHLD = getattr(signal, 'SIGCHLD', None)
b7dbe957585c util: use safehasattr or getattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents: 14942
diff changeset
   602
    if SIGCHLD is not None:
b7dbe957585c util: use safehasattr or getattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents: 14942
diff changeset
   603
        prevhandler = signal.signal(SIGCHLD, handler)
10344
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   604
    try:
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   605
        pid = spawndetached(args)
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   606
        while not condfn():
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   607
            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
   608
                return -1
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   609
            time.sleep(0.1)
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   610
        return pid
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   611
    finally:
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   612
        if prevhandler is not None:
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   613
            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
   614
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   615
38526
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   616
@contextlib.contextmanager
41076
8ecb17b7f432 procutil: correct spelling of uninterruptable -> uninterruptible
Kyle Lippincott <spectral@google.com>
parents: 40712
diff changeset
   617
def uninterruptible(warn):
38526
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   618
    """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
   619
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   620
    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
   621
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   622
    Args:
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   623
      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
   624
            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
   625
    """
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   626
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   627
    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
   628
    shouldbail = []
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   629
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   630
    def disabledsiginthandler(*args):
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   631
        if warn():
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   632
            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
   633
            del oldsiginthandler[0]
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   634
        shouldbail.append(True)
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
    try:
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   637
        try:
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   638
            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
   639
        except ValueError:
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   640
            # 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
   641
            del oldsiginthandler[0]
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   642
        yield
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   643
    finally:
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   644
        if oldsiginthandler:
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   645
            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
   646
        if shouldbail:
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   647
            raise KeyboardInterrupt
40497
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   648
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   649
40497
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   650
if pycompat.iswindows:
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   651
    # 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
   652
    # 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
   653
    # No stdlib constant exists for this value
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   654
    DETACHED_PROCESS = 0x00000008
40536
1d3bed7d2923 procutil: import concerns about creationflags on Windows from D1701
Boris Feld <boris.feld@octobus.net>
parents: 40498
diff changeset
   655
    # 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
   656
    # 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
   657
    # 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
   658
    _creationflags = (
54f4d094bab1 procutil: suppress pytype warnings around windows-only attributes
Augie Fackler <augie@google.com>
parents: 43165
diff changeset
   659
        DETACHED_PROCESS
54f4d094bab1 procutil: suppress pytype warnings around windows-only attributes
Augie Fackler <augie@google.com>
parents: 43165
diff changeset
   660
        | 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
   661
    )
40497
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   662
42496
ca1014ad3de4 procutil: allow callers of runbgcommand to assume the process starts
Augie Fackler <augie@google.com>
parents: 41832
diff changeset
   663
    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
   664
        script,
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   665
        env,
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   666
        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
   667
        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
   668
        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
   669
        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
   670
        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
   671
        stdin_bytes=None,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   672
    ):
40497
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   673
        '''Spawn a command without waiting for it to finish.'''
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   674
        # 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
   675
        # 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
   676
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
   677
        try:
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
   678
            stdin = None
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
   679
            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
   680
                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
   681
                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
   682
                stdin.flush()
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
   683
                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
   684
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
   685
            p = subprocess.Popen(
46030
2cf61e66c6d0 merge with stable
Augie Fackler <augie@google.com>
parents: 45942 46019
diff changeset
   686
                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
   687
                shell=shell,
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
   688
                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
   689
                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
   690
                creationflags=_creationflags,
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
   691
                stdin=stdin,
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
   692
                stdout=stdout,
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
   693
                stderr=stderr,
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
   694
            )
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
   695
            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
   696
                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
   697
        finally:
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
   698
            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
   699
                stdin.close()
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   700
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   701
40497
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   702
else:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   703
46889
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   704
    def runbgcommandpy3(
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   705
        cmd,
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   706
        env,
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   707
        shell=False,
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   708
        stdout=None,
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   709
        stderr=None,
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   710
        ensurestart=True,
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   711
        record_wait=None,
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   712
        stdin_bytes=None,
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   713
    ):
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   714
        """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
   715
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   716
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   717
        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
   718
        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
   719
        `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
   720
        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
   721
        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
   722
        if pycompat.isdarwin:
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   723
            # 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
   724
            # 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
   725
            gui()
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   726
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   727
        if shell:
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   728
            script = cmd
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   729
        else:
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   730
            if isinstance(cmd, bytes):
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   731
                cmd = [cmd]
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   732
            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
   733
        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
   734
            # 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
   735
            script = b'( %s ) &' % script
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   736
            start_new_session = True
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   737
        else:
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   738
            start_new_session = False
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   739
            ensurestart = True
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   740
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   741
        try:
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   742
            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
   743
                stdin = subprocess.DEVNULL
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   744
            else:
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   745
                stdin = pycompat.unnamedtempfile()
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   746
                stdin.write(stdin_bytes)
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   747
                stdin.flush()
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   748
                stdin.seek(0)
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   749
            if stdout is None:
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   750
                stdout = subprocess.DEVNULL
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   751
            if stderr is None:
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   752
                stderr = subprocess.DEVNULL
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   753
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   754
            p = subprocess.Popen(
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   755
                script,
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   756
                shell=True,
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   757
                env=env,
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   758
                close_fds=True,
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   759
                stdin=stdin,
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   760
                stdout=stdout,
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   761
                stderr=stderr,
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   762
                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
   763
            )
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   764
        except Exception:
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   765
            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
   766
                record_wait(255)
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   767
            raise
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   768
        finally:
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   769
            if stdin_bytes is not None:
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   770
                stdin.close()
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   771
        if not ensurestart:
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   772
            # 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
   773
            # 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
   774
            # 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
   775
            # 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
   776
            # 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
   777
            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
   778
            t.daemon = True
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   779
            t.start()
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   780
        else:
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   781
            returncode = p.wait
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   782
            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
   783
                record_wait(returncode)
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   784
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   785
    def runbgcommandpy2(
43848
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   786
        cmd,
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   787
        env,
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   788
        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
   789
        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
   790
        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
   791
        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
   792
        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
   793
        stdin_bytes=None,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   794
    ):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45852
diff changeset
   795
        """Spawn a command without waiting for it to finish.
43848
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   796
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   797
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   798
        When `record_wait` is not None, the spawned process will not be fully
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   799
        detached and the `record_wait` argument will be called with a the
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   800
        `Subprocess.wait` function for the spawned process.  This is mostly
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   801
        useful for developers that need to make sure the spawned process
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45852
diff changeset
   802
        finished before a certain point. (eg: writing test)"""
43912
a89381e04c58 procutil: try and avoid angering CoreFoundation on macOS
Augie Fackler <augie@google.com>
parents: 43862
diff changeset
   803
        if pycompat.isdarwin:
a89381e04c58 procutil: try and avoid angering CoreFoundation on macOS
Augie Fackler <augie@google.com>
parents: 43862
diff changeset
   804
            # avoid crash in CoreFoundation in case another thread
a89381e04c58 procutil: try and avoid angering CoreFoundation on macOS
Augie Fackler <augie@google.com>
parents: 43862
diff changeset
   805
            # calls gui() while we're calling fork().
a89381e04c58 procutil: try and avoid angering CoreFoundation on macOS
Augie Fackler <augie@google.com>
parents: 43862
diff changeset
   806
            gui()
a89381e04c58 procutil: try and avoid angering CoreFoundation on macOS
Augie Fackler <augie@google.com>
parents: 43862
diff changeset
   807
40497
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   808
        # double-fork to completely detach from the parent process
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   809
        # based on http://code.activestate.com/recipes/278731
43848
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   810
        if record_wait is None:
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   811
            pid = os.fork()
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   812
            if pid:
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   813
                if not ensurestart:
44781
ed684a82e29b procutil: always waiting on child processes to prevent zombies with 'hg serve'
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 43912
diff changeset
   814
                    # Even though we're not waiting on the child process,
ed684a82e29b procutil: always waiting on child processes to prevent zombies with 'hg serve'
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 43912
diff changeset
   815
                    # we still must call waitpid() on it at some point so
ed684a82e29b procutil: always waiting on child processes to prevent zombies with 'hg serve'
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 43912
diff changeset
   816
                    # it's not a zombie/defunct. This is especially relevant for
ed684a82e29b procutil: always waiting on child processes to prevent zombies with 'hg serve'
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 43912
diff changeset
   817
                    # chg since the parent process won't die anytime soon.
ed684a82e29b procutil: always waiting on child processes to prevent zombies with 'hg serve'
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 43912
diff changeset
   818
                    # We use a thread to make the overhead tiny.
ed684a82e29b procutil: always waiting on child processes to prevent zombies with 'hg serve'
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 43912
diff changeset
   819
                    def _do_wait():
ed684a82e29b procutil: always waiting on child processes to prevent zombies with 'hg serve'
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 43912
diff changeset
   820
                        os.waitpid(pid, 0)
44812
79f6f856c53f formatting: add missing newline
Raphaël Gomès <rgomes@octobus.net>
parents: 44781
diff changeset
   821
44978
95c672c07116 procutil: make recent fix for zombies compatible with py2
Martin von Zweigbergk <martinvonz@google.com>
parents: 44919
diff changeset
   822
                    t = threading.Thread(target=_do_wait)
95c672c07116 procutil: make recent fix for zombies compatible with py2
Martin von Zweigbergk <martinvonz@google.com>
parents: 44919
diff changeset
   823
                    t.daemon = True
95c672c07116 procutil: make recent fix for zombies compatible with py2
Martin von Zweigbergk <martinvonz@google.com>
parents: 44919
diff changeset
   824
                    t.start()
43848
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   825
                    return
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   826
                # Parent process
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   827
                (_pid, status) = os.waitpid(pid, 0)
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   828
                if os.WIFEXITED(status):
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   829
                    returncode = os.WEXITSTATUS(status)
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   830
                else:
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   831
                    returncode = -(os.WTERMSIG(status))
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   832
                if returncode != 0:
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   833
                    # The child process's return code is 0 on success, an errno
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   834
                    # value on failure, or 255 if we don't have a valid errno
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   835
                    # value.
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   836
                    #
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   837
                    # (It would be slightly nicer to return the full exception info
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   838
                    # over a pipe as the subprocess module does.  For now it
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   839
                    # doesn't seem worth adding that complexity here, though.)
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   840
                    if returncode == 255:
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   841
                        returncode = errno.EINVAL
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   842
                    raise OSError(
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   843
                        returncode,
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   844
                        b'error running %r: %s'
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   845
                        % (cmd, os.strerror(returncode)),
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   846
                    )
42496
ca1014ad3de4 procutil: allow callers of runbgcommand to assume the process starts
Augie Fackler <augie@google.com>
parents: 41832
diff changeset
   847
                return
40497
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   848
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   849
        returncode = 255
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   850
        try:
43848
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   851
            if record_wait is None:
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   852
                # Start a new session
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   853
                os.setsid()
45786
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
   854
            # connect stdin to devnull to make sure the subprocess can't
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
   855
            # muck up that stream for mercurial.
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
   856
            if stdin_bytes is None:
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
   857
                stdin = open(os.devnull, b'r')
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
   858
            else:
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
   859
                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
   860
                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
   861
                stdin.flush()
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
   862
                stdin.seek(0)
40497
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   863
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   864
            if stdout is None:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   865
                stdout = open(os.devnull, b'w')
40497
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   866
            if stderr is None:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   867
                stderr = open(os.devnull, b'w')
40497
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   868
43848
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   869
            p = subprocess.Popen(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   870
                cmd,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   871
                shell=shell,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   872
                env=env,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   873
                close_fds=True,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   874
                stdin=stdin,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   875
                stdout=stdout,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   876
                stderr=stderr,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   877
            )
43848
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   878
            if record_wait is not None:
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   879
                record_wait(p.wait)
40497
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   880
            returncode = 0
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   881
        except EnvironmentError as ex:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   882
            returncode = ex.errno & 0xFF
40497
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   883
            if returncode == 0:
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   884
                # This shouldn't happen, but just in case make sure the
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   885
                # return code is never 0 here.
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   886
                returncode = 255
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   887
        except Exception:
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   888
            returncode = 255
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   889
        finally:
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   890
            # mission accomplished, this child needs to exit and not
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   891
            # continue the hg process here.
45786
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
   892
            stdin.close()
43848
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   893
            if record_wait is None:
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   894
                os._exit(returncode)
46889
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   895
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   896
    if pycompat.ispy3:
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   897
        # This branch is more robust, because it avoids running python
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   898
        # code (hence gc finalizers, like sshpeer.__del__, which
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   899
        # blocks).  But we can't easily do the equivalent in py2,
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   900
        # because of the lack of start_new_session=True flag. Given
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   901
        # that the py2 branch should die soon, the short-lived
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   902
        # duplication seems acceptable.
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   903
        runbgcommand = runbgcommandpy3
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   904
    else:
8759e22f1649 procutil: avoid using os.fork() to implement runbgcommand
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 46819
diff changeset
   905
        runbgcommand = runbgcommandpy2