mercurial/utils/procutil.py
author Manuel Jacob <me@manueljacob.de>
Sun, 05 Jul 2020 13:09:22 +0200
changeset 45045 8403cc54bc83
parent 45043 be58fb1eaa73
child 45056 9694895749ad
permissions -rw-r--r--
procutil: make mercurial.utils.procutil.stderr unbuffered For most Mercurial code, it doesn’t make a difference, as the ui object flushes stderr explicitly (after the change, we could get rid of the explicit flush). One example where it makes a observable difference is mercurial.util.timed(). Without the patch, the time is not immediately shown on Python 3. With the patch, it’s shown immediately on all Python versions and platforms.
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>
8b2cd04a6e97 put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents: 8225
diff changeset
     4
#  Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
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
45039
2bfbd7d2c204 procutil: define LineBufferedWrapper on all Python versions
Manuel Jacob <me@manueljacob.de>
parents: 45000
diff changeset
    53
class LineBufferedWrapper(object):
2bfbd7d2c204 procutil: define LineBufferedWrapper on all Python versions
Manuel Jacob <me@manueljacob.de>
parents: 45000
diff changeset
    54
    def __init__(self, orig):
2bfbd7d2c204 procutil: define LineBufferedWrapper on all Python versions
Manuel Jacob <me@manueljacob.de>
parents: 45000
diff changeset
    55
        self.orig = orig
44950
f9734b2d59cc py3: make stdout line-buffered if connected to a TTY
Manuel Jacob <me@manueljacob.de>
parents: 44867
diff changeset
    56
45039
2bfbd7d2c204 procutil: define LineBufferedWrapper on all Python versions
Manuel Jacob <me@manueljacob.de>
parents: 45000
diff changeset
    57
    def __getattr__(self, attr):
2bfbd7d2c204 procutil: define LineBufferedWrapper on all Python versions
Manuel Jacob <me@manueljacob.de>
parents: 45000
diff changeset
    58
        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
    59
45039
2bfbd7d2c204 procutil: define LineBufferedWrapper on all Python versions
Manuel Jacob <me@manueljacob.de>
parents: 45000
diff changeset
    60
    def write(self, s):
2bfbd7d2c204 procutil: define LineBufferedWrapper on all Python versions
Manuel Jacob <me@manueljacob.de>
parents: 45000
diff changeset
    61
        orig = self.orig
2bfbd7d2c204 procutil: define LineBufferedWrapper on all Python versions
Manuel Jacob <me@manueljacob.de>
parents: 45000
diff changeset
    62
        res = orig.write(s)
2bfbd7d2c204 procutil: define LineBufferedWrapper on all Python versions
Manuel Jacob <me@manueljacob.de>
parents: 45000
diff changeset
    63
        if s.endswith(b'\n'):
2bfbd7d2c204 procutil: define LineBufferedWrapper on all Python versions
Manuel Jacob <me@manueljacob.de>
parents: 45000
diff changeset
    64
            orig.flush()
2bfbd7d2c204 procutil: define LineBufferedWrapper on all Python versions
Manuel Jacob <me@manueljacob.de>
parents: 45000
diff changeset
    65
        return res
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
2bfbd7d2c204 procutil: define LineBufferedWrapper on all Python versions
Manuel Jacob <me@manueljacob.de>
parents: 45000
diff changeset
    68
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
    69
f9734b2d59cc py3: make stdout line-buffered if connected to a TTY
Manuel Jacob <me@manueljacob.de>
parents: 44867
diff changeset
    70
45040
fd205a9c358a procutil: factor out conditional creation of LineBufferedWrapper
Manuel Jacob <me@manueljacob.de>
parents: 45039
diff changeset
    71
def make_line_buffered(stream):
fd205a9c358a procutil: factor out conditional creation of LineBufferedWrapper
Manuel Jacob <me@manueljacob.de>
parents: 45039
diff changeset
    72
    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
    73
        # 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
    74
        # 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
    75
        # 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
    76
        # to emulate line buffering.
fd205a9c358a procutil: factor out conditional creation of LineBufferedWrapper
Manuel Jacob <me@manueljacob.de>
parents: 45039
diff changeset
    77
        return stream
fd205a9c358a procutil: factor out conditional creation of LineBufferedWrapper
Manuel Jacob <me@manueljacob.de>
parents: 45039
diff changeset
    78
    if isinstance(stream, LineBufferedWrapper):
fd205a9c358a procutil: factor out conditional creation of LineBufferedWrapper
Manuel Jacob <me@manueljacob.de>
parents: 45039
diff changeset
    79
        return stream
fd205a9c358a procutil: factor out conditional creation of LineBufferedWrapper
Manuel Jacob <me@manueljacob.de>
parents: 45039
diff changeset
    80
    return LineBufferedWrapper(stream)
fd205a9c358a procutil: factor out conditional creation of LineBufferedWrapper
Manuel Jacob <me@manueljacob.de>
parents: 45039
diff changeset
    81
fd205a9c358a procutil: factor out conditional creation of LineBufferedWrapper
Manuel Jacob <me@manueljacob.de>
parents: 45039
diff changeset
    82
45041
1053f878dd46 procutil: move assignments closer to reassignments
Manuel Jacob <me@manueljacob.de>
parents: 45040
diff changeset
    83
stderr = pycompat.stderr
1053f878dd46 procutil: move assignments closer to reassignments
Manuel Jacob <me@manueljacob.de>
parents: 45040
diff changeset
    84
stdin = pycompat.stdin
1053f878dd46 procutil: move assignments closer to reassignments
Manuel Jacob <me@manueljacob.de>
parents: 45040
diff changeset
    85
stdout = pycompat.stdout
1053f878dd46 procutil: move assignments closer to reassignments
Manuel Jacob <me@manueljacob.de>
parents: 45040
diff changeset
    86
45043
be58fb1eaa73 procutil: make stdout line-buffered on Windows if connected to TTY
Manuel Jacob <me@manueljacob.de>
parents: 45042
diff changeset
    87
if pycompat.iswindows:
be58fb1eaa73 procutil: make stdout line-buffered on Windows if connected to TTY
Manuel Jacob <me@manueljacob.de>
parents: 45042
diff changeset
    88
    stdout = platform.winstdout(stdout)
be58fb1eaa73 procutil: make stdout line-buffered on Windows if connected to TTY
Manuel Jacob <me@manueljacob.de>
parents: 45042
diff changeset
    89
30876
3a4c0905f357 util: always force line buffered stdout when stdout is a tty (BC)
Simon Farnsworth <simonfar@fb.com>
parents: 30854
diff changeset
    90
# glibc determines buffering on first write to stdout - if we replace a TTY
3a4c0905f357 util: always force line buffered stdout when stdout is a tty (BC)
Simon Farnsworth <simonfar@fb.com>
parents: 30854
diff changeset
    91
# destined stdout with a pipe destined stdout (e.g. pager), we want line
45043
be58fb1eaa73 procutil: make stdout line-buffered on Windows if connected to TTY
Manuel Jacob <me@manueljacob.de>
parents: 45042
diff changeset
    92
# buffering.
30876
3a4c0905f357 util: always force line buffered stdout when stdout is a tty (BC)
Simon Farnsworth <simonfar@fb.com>
parents: 30854
diff changeset
    93
if isatty(stdout):
45043
be58fb1eaa73 procutil: make stdout line-buffered on Windows if connected to TTY
Manuel Jacob <me@manueljacob.de>
parents: 45042
diff changeset
    94
    if pycompat.ispy3 or pycompat.iswindows:
44950
f9734b2d59cc py3: make stdout line-buffered if connected to a TTY
Manuel Jacob <me@manueljacob.de>
parents: 44867
diff changeset
    95
        # On Python 3, buffered binary streams can't be set line-buffered.
45043
be58fb1eaa73 procutil: make stdout line-buffered on Windows if connected to TTY
Manuel Jacob <me@manueljacob.de>
parents: 45042
diff changeset
    96
        # On Python 2, Windows doesn't support line buffering.
44950
f9734b2d59cc py3: make stdout line-buffered if connected to a TTY
Manuel Jacob <me@manueljacob.de>
parents: 44867
diff changeset
    97
        # Therefore we have a wrapper that implements line buffering.
45040
fd205a9c358a procutil: factor out conditional creation of LineBufferedWrapper
Manuel Jacob <me@manueljacob.de>
parents: 45039
diff changeset
    98
        stdout = make_line_buffered(stdout)
44950
f9734b2d59cc py3: make stdout line-buffered if connected to a TTY
Manuel Jacob <me@manueljacob.de>
parents: 44867
diff changeset
    99
    else:
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43503
diff changeset
   100
        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
   101
45045
8403cc54bc83 procutil: make mercurial.utils.procutil.stderr unbuffered
Manuel Jacob <me@manueljacob.de>
parents: 45043
diff changeset
   102
# stderr should be unbuffered
8403cc54bc83 procutil: make mercurial.utils.procutil.stderr unbuffered
Manuel Jacob <me@manueljacob.de>
parents: 45043
diff changeset
   103
if pycompat.ispy3:
8403cc54bc83 procutil: make mercurial.utils.procutil.stderr unbuffered
Manuel Jacob <me@manueljacob.de>
parents: 45043
diff changeset
   104
    # On Python 3, buffered streams may expose an underlying raw stream. This is
8403cc54bc83 procutil: make mercurial.utils.procutil.stderr unbuffered
Manuel Jacob <me@manueljacob.de>
parents: 45043
diff changeset
   105
    # definitively the case for the streams initialized by the interpreter. If
8403cc54bc83 procutil: make mercurial.utils.procutil.stderr unbuffered
Manuel Jacob <me@manueljacob.de>
parents: 45043
diff changeset
   106
    # the attribute isn't present, the stream is already unbuffered or doesn't
8403cc54bc83 procutil: make mercurial.utils.procutil.stderr unbuffered
Manuel Jacob <me@manueljacob.de>
parents: 45043
diff changeset
   107
    # expose an underlying raw stream, in which case we use the stream as-is.
8403cc54bc83 procutil: make mercurial.utils.procutil.stderr unbuffered
Manuel Jacob <me@manueljacob.de>
parents: 45043
diff changeset
   108
    stderr = getattr(stderr, 'raw', stderr)
8403cc54bc83 procutil: make mercurial.utils.procutil.stderr unbuffered
Manuel Jacob <me@manueljacob.de>
parents: 45043
diff changeset
   109
elif pycompat.iswindows:
8403cc54bc83 procutil: make mercurial.utils.procutil.stderr unbuffered
Manuel Jacob <me@manueljacob.de>
parents: 45043
diff changeset
   110
    # On Windows, stderr is buffered at least when connected to a pipe.
8403cc54bc83 procutil: make mercurial.utils.procutil.stderr unbuffered
Manuel Jacob <me@manueljacob.de>
parents: 45043
diff changeset
   111
    stderr = os.fdopen(stderr.fileno(), 'wb', 0)
8403cc54bc83 procutil: make mercurial.utils.procutil.stderr unbuffered
Manuel Jacob <me@manueljacob.de>
parents: 45043
diff changeset
   112
# On other platforms, stderr is always unbuffered.
8403cc54bc83 procutil: make mercurial.utils.procutil.stderr unbuffered
Manuel Jacob <me@manueljacob.de>
parents: 45043
diff changeset
   113
14926
4e7e63fc685a util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents: 14918
diff changeset
   114
4e7e63fc685a util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents: 14918
diff changeset
   115
findexe = platform.findexe
37115
49d6ba67c93f util: mark platform-specific gethgcmd() as private
Yuya Nishihara <yuya@tcha.org>
parents: 37099
diff changeset
   116
_gethgcmd = platform.gethgcmd
14926
4e7e63fc685a util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents: 14918
diff changeset
   117
getuser = platform.getuser
28027
14033c5dd261 util: enable getpid to be replaced
timeless <timeless@mozdev.org>
parents: 27785
diff changeset
   118
getpid = os.getpid
14926
4e7e63fc685a util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents: 14918
diff changeset
   119
hidewindow = platform.hidewindow
22245
234e4c24b980 platform: implement readpipe()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21914
diff changeset
   120
readpipe = platform.readpipe
14926
4e7e63fc685a util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents: 14918
diff changeset
   121
setbinary = platform.setbinary
4e7e63fc685a util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents: 14918
diff changeset
   122
setsignalhandler = platform.setsignalhandler
4e7e63fc685a util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents: 14918
diff changeset
   123
shellquote = platform.shellquote
36415
0cb09c322647 util: factor out shellsplit() function
Yuya Nishihara <yuya@tcha.org>
parents: 36362
diff changeset
   124
shellsplit = platform.shellsplit
14926
4e7e63fc685a util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents: 14918
diff changeset
   125
spawndetached = platform.spawndetached
4e7e63fc685a util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents: 14918
diff changeset
   126
sshargs = platform.sshargs
4e7e63fc685a util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents: 14918
diff changeset
   127
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
   128
32208
d74b0cff94a9 osutil: proxy through util (and platform) modules (API)
Yuya Nishihara <yuya@tcha.org>
parents: 32201
diff changeset
   129
try:
d74b0cff94a9 osutil: proxy through util (and platform) modules (API)
Yuya Nishihara <yuya@tcha.org>
parents: 32201
diff changeset
   130
    setprocname = osutil.setprocname
d74b0cff94a9 osutil: proxy through util (and platform) modules (API)
Yuya Nishihara <yuya@tcha.org>
parents: 32201
diff changeset
   131
except AttributeError:
d74b0cff94a9 osutil: proxy through util (and platform) modules (API)
Yuya Nishihara <yuya@tcha.org>
parents: 32201
diff changeset
   132
    pass
35460
8652ab4046e4 osutil: add a function to unblock signals
Jun Wu <quark@fb.com>
parents: 35145
diff changeset
   133
try:
8652ab4046e4 osutil: add a function to unblock signals
Jun Wu <quark@fb.com>
parents: 35145
diff changeset
   134
    unblocksignal = osutil.unblocksignal
8652ab4046e4 osutil: add a function to unblock signals
Jun Wu <quark@fb.com>
parents: 35145
diff changeset
   135
except AttributeError:
8652ab4046e4 osutil: add a function to unblock signals
Jun Wu <quark@fb.com>
parents: 35145
diff changeset
   136
    pass
32208
d74b0cff94a9 osutil: proxy through util (and platform) modules (API)
Yuya Nishihara <yuya@tcha.org>
parents: 32201
diff changeset
   137
34646
238abf65a8ad codemod: use pycompat.isposix
Jun Wu <quark@fb.com>
parents: 34645
diff changeset
   138
closefds = pycompat.isposix
10197
29e3c4a7699b subrepo: normalize svn output line-endings
Patrick Mezard <pmezard@gmail.com>
parents: 9996
diff changeset
   139
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   140
37460
a6c6b7beb025 procutil: unify platform.explainexit()
Yuya Nishihara <yuya@tcha.org>
parents: 37459
diff changeset
   141
def explainexit(code):
37463
bbd240f81ac5 procutil: make explainexit() simply return a message (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37462
diff changeset
   142
    """return a message describing a subprocess status
37460
a6c6b7beb025 procutil: unify platform.explainexit()
Yuya Nishihara <yuya@tcha.org>
parents: 37459
diff changeset
   143
    (codes from kill are negative - not os.system/wait encoding)"""
a6c6b7beb025 procutil: unify platform.explainexit()
Yuya Nishihara <yuya@tcha.org>
parents: 37459
diff changeset
   144
    if code >= 0:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   145
        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
   146
    return _(b"killed by signal %d") % -code
37460
a6c6b7beb025 procutil: unify platform.explainexit()
Yuya Nishihara <yuya@tcha.org>
parents: 37459
diff changeset
   147
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   148
37459
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   149
class _pfile(object):
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   150
    """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
   151
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   152
    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
   153
        self._proc = proc
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   154
        self._fp = fp
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   155
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   156
    def close(self):
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   157
        # 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
   158
        self._fp.close()
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   159
        return self._proc.wait()
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   160
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   161
    def __iter__(self):
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   162
        return iter(self._fp)
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   163
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   164
    def __getattr__(self, attr):
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   165
        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
   166
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   167
    def __enter__(self):
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   168
        return self
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   169
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   170
    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
   171
        self.close()
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   172
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   173
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   174
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
   175
    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
   176
        return _popenreader(cmd, bufsize)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   177
    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
   178
        return _popenwriter(cmd, bufsize)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   179
    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
   180
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   181
37459
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   182
def _popenreader(cmd, bufsize):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   183
    p = subprocess.Popen(
44867
8e8fd938ca07 cleanup: eliminate procutil.quotecommand()
Manuel Jacob <me@manueljacob.de>
parents: 44812
diff changeset
   184
        tonativestr(cmd),
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   185
        shell=True,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   186
        bufsize=bufsize,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   187
        close_fds=closefds,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   188
        stdout=subprocess.PIPE,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   189
    )
37459
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   190
    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
   191
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   192
37459
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   193
def _popenwriter(cmd, bufsize):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   194
    p = subprocess.Popen(
44867
8e8fd938ca07 cleanup: eliminate procutil.quotecommand()
Manuel Jacob <me@manueljacob.de>
parents: 44812
diff changeset
   195
        tonativestr(cmd),
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   196
        shell=True,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   197
        bufsize=bufsize,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   198
        close_fds=closefds,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   199
        stdin=subprocess.PIPE,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   200
    )
37459
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37220
diff changeset
   201
    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
   202
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   203
37464
632b92899203 procutil: drop unused 'newlines' option from popen*() (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37463
diff changeset
   204
def popen2(cmd, env=None):
9089
8ec39725d966 util: remove unused bufsize argument
Martin Geisler <mg@lazybytes.net>
parents: 9084
diff changeset
   205
    # 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
   206
    # 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
   207
    # 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
   208
    p = subprocess.Popen(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   209
        tonativestr(cmd),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   210
        shell=True,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   211
        bufsize=-1,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   212
        close_fds=closefds,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   213
        stdin=subprocess.PIPE,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   214
        stdout=subprocess.PIPE,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   215
        env=tonativeenv(env),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   216
    )
8280
0b02d98d44d0 util: always use subprocess
Martin Geisler <mg@lazybytes.net>
parents: 8257
diff changeset
   217
    return p.stdin, p.stdout
10197
29e3c4a7699b subrepo: normalize svn output line-endings
Patrick Mezard <pmezard@gmail.com>
parents: 9996
diff changeset
   218
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   219
37464
632b92899203 procutil: drop unused 'newlines' option from popen*() (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37463
diff changeset
   220
def popen3(cmd, env=None):
632b92899203 procutil: drop unused 'newlines' option from popen*() (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37463
diff changeset
   221
    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
   222
    return stdin, stdout, stderr
9baf4330d88f sshpeer: store subprocess so it cleans up correctly
Durham Goode <durham@fb.com>
parents: 18736
diff changeset
   223
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   224
37464
632b92899203 procutil: drop unused 'newlines' option from popen*() (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37463
diff changeset
   225
def popen4(cmd, env=None, bufsize=-1):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   226
    p = subprocess.Popen(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   227
        tonativestr(cmd),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   228
        shell=True,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   229
        bufsize=bufsize,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   230
        close_fds=closefds,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   231
        stdin=subprocess.PIPE,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   232
        stdout=subprocess.PIPE,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   233
        stderr=subprocess.PIPE,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   234
        env=tonativeenv(env),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   235
    )
18759
9baf4330d88f sshpeer: store subprocess so it cleans up correctly
Durham Goode <durham@fb.com>
parents: 18736
diff changeset
   236
    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
   237
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   238
1293
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   239
def pipefilter(s, cmd):
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   240
    '''filter string S through command CMD, returning its output'''
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   241
    p = subprocess.Popen(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   242
        tonativestr(cmd),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   243
        shell=True,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   244
        close_fds=closefds,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   245
        stdin=subprocess.PIPE,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   246
        stdout=subprocess.PIPE,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   247
    )
8302
d2ad8c066676 util: simplify pipefilter and avoid subprocess race
Martin Geisler <mg@lazybytes.net>
parents: 8299
diff changeset
   248
    pout, perr = p.communicate(s)
d2ad8c066676 util: simplify pipefilter and avoid subprocess race
Martin Geisler <mg@lazybytes.net>
parents: 8299
diff changeset
   249
    return pout
419
28511fc21073 [PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff changeset
   250
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   251
1293
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   252
def tempfilter(s, cmd):
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   253
    '''filter string S through a pair of temporary files with CMD.
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   254
    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
   255
    with the strings INFILE and OUTFILE replaced by the real names of
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   256
    the temporary files generated.'''
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   257
    inname, outname = None, None
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   258
    try:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   259
        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
   260
        fp = os.fdopen(infd, 'wb')
1293
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   261
        fp.write(s)
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   262
        fp.close()
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   263
        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
   264
        os.close(outfd)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   265
        cmd = cmd.replace(b'INFILE', inname)
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   266
        cmd = cmd.replace(b'OUTFILE', outname)
37461
538353b80676 procutil: fix error message of tempfile filter
Yuya Nishihara <yuya@tcha.org>
parents: 37460
diff changeset
   267
        code = system(cmd)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   268
        if pycompat.sysplatform == b'OpenVMS' and code & 1:
4720
72fb6f10fac1 OpenVMS patches
Jean-Francois PIERONNE <jf.pieronne@laposte.net>
parents: 4708
diff changeset
   269
            code = 0
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
   270
        if code:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   271
            raise error.Abort(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   272
                _(b"command '%s' failed: %s") % (cmd, explainexit(code))
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   273
            )
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   274
        with open(outname, b'rb') as fp:
37117
e7b517809ebc util: stop using readfile() in tempfilter()
Yuya Nishihara <yuya@tcha.org>
parents: 37116
diff changeset
   275
            return fp.read()
1293
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   276
    finally:
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   277
        try:
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
   278
            if inname:
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
   279
                os.unlink(inname)
14004
97ed99d1f419 eliminate various naked except clauses
Idan Kamara <idankk86@gmail.com>
parents: 13985
diff changeset
   280
        except OSError:
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
   281
            pass
1293
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   282
        try:
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
   283
            if outname:
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
   284
                os.unlink(outname)
14004
97ed99d1f419 eliminate various naked except clauses
Idan Kamara <idankk86@gmail.com>
parents: 13985
diff changeset
   285
        except OSError:
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
   286
            pass
1293
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   287
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   288
37116
7ccc9b8aca4c util: mark filtertable as private constant
Yuya Nishihara <yuya@tcha.org>
parents: 37115
diff changeset
   289
_filtertable = {
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   290
    b'tempfile:': tempfilter,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   291
    b'pipe:': pipefilter,
37116
7ccc9b8aca4c util: mark filtertable as private constant
Yuya Nishihara <yuya@tcha.org>
parents: 37115
diff changeset
   292
}
1293
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   293
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   294
1293
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   295
def filter(s, cmd):
43787
be8552f25cab cleanup: fix docstring formatting
Matt Harbison <matt_harbison@yahoo.com>
parents: 43671
diff changeset
   296
    """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
   297
    output"""
43106
d783f945a701 py3: finish porting iteritems() to pycompat and remove source transformer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43096
diff changeset
   298
    for name, fn in pycompat.iteritems(_filtertable):
1293
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   299
        if cmd.startswith(name):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   300
            return fn(s, cmd[len(name) :].lstrip())
1293
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   301
    return pipefilter(s, cmd)
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
   302
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   303
22632
db15bb2d6323 util: move _hgexecutable a few lines, closer to where it is used
Mads Kiilerich <madski@unity3d.com>
parents: 22245
diff changeset
   304
_hgexecutable = None
db15bb2d6323 util: move _hgexecutable a few lines, closer to where it is used
Mads Kiilerich <madski@unity3d.com>
parents: 22245
diff changeset
   305
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   306
5062
3d35c8cb5eb4 Simplify/correct finding the hg executable (fixes issue644)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4832
diff changeset
   307
def hgexecutable():
3d35c8cb5eb4 Simplify/correct finding the hg executable (fixes issue644)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4832
diff changeset
   308
    """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
   309
3d35c8cb5eb4 Simplify/correct finding the hg executable (fixes issue644)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4832
diff changeset
   310
    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
   311
    """
3d35c8cb5eb4 Simplify/correct finding the hg executable (fixes issue644)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4832
diff changeset
   312
    if _hgexecutable is None:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   313
        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
   314
        mainmod = sys.modules['__main__']
6500
a3175cd7dbec Tidy code, fix typo
Bryan O'Sullivan <bos@serpentine.com>
parents: 6499
diff changeset
   315
        if hg:
14229
85fd8402cbc4 rename util.set_hgexecutable to _sethgexecutable
Adrian Buehlmann <adrian@cadifra.com>
parents: 14228
diff changeset
   316
            _sethgexecutable(hg)
43671
664e24207728 procutil: move mainfrozen() to new resourceutil.py
Martin von Zweigbergk <martinvonz@google.com>
parents: 43657
diff changeset
   317
        elif resourceutil.mainfrozen():
43657
38387f9e4d22 py3: use native string for 'macosx_app'
Martin von Zweigbergk <martinvonz@google.com>
parents: 43656
diff changeset
   318
            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
   319
                # Env variable set by py2app
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   320
                _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
   321
            else:
30669
10b17ed9b591 py3: replace sys.executable with pycompat.sysexecutable
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30642
diff changeset
   322
                _sethgexecutable(pycompat.sysexecutable)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   323
        elif (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   324
            not pycompat.iswindows
43656
47d983f0af65 py3: drop an unnecessary fsencode() before comparing with constant
Martin von Zweigbergk <martinvonz@google.com>
parents: 43655
diff changeset
   325
            and os.path.basename(getattr(mainmod, '__file__', '')) == 'hg'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   326
        ):
31074
2912b06905dc py3: use pycompat.fsencode() to convert __file__ to bytes
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30988
diff changeset
   327
            _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
   328
        else:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   329
            _sethgexecutable(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   330
                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
   331
            )
5062
3d35c8cb5eb4 Simplify/correct finding the hg executable (fixes issue644)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4832
diff changeset
   332
    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
   333
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   334
14229
85fd8402cbc4 rename util.set_hgexecutable to _sethgexecutable
Adrian Buehlmann <adrian@cadifra.com>
parents: 14228
diff changeset
   335
def _sethgexecutable(path):
5062
3d35c8cb5eb4 Simplify/correct finding the hg executable (fixes issue644)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4832
diff changeset
   336
    """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
   337
    global _hgexecutable
5062
3d35c8cb5eb4 Simplify/correct finding the hg executable (fixes issue644)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4832
diff changeset
   338
    _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
   339
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   340
36793
eca1051e6c22 util: add public isstdin/isstdout() functions
Yuya Nishihara <yuya@tcha.org>
parents: 36791
diff changeset
   341
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
   342
    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
   343
    try:
36793
eca1051e6c22 util: add public isstdin/isstdout() functions
Yuya Nishihara <yuya@tcha.org>
parents: 36791
diff changeset
   344
        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
   345
    except io.UnsupportedOperation:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   346
        return False  # fileno() raised UnsupportedOperation
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   347
26450
1138e1d05207 util.system: compare fileno to see if it needs stdout redirection
Yuya Nishihara <yuya@tcha.org>
parents: 26392
diff changeset
   348
36793
eca1051e6c22 util: add public isstdin/isstdout() functions
Yuya Nishihara <yuya@tcha.org>
parents: 36791
diff changeset
   349
def isstdin(f):
eca1051e6c22 util: add public isstdin/isstdout() functions
Yuya Nishihara <yuya@tcha.org>
parents: 36791
diff changeset
   350
    return _testfileno(f, sys.__stdin__)
eca1051e6c22 util: add public isstdin/isstdout() functions
Yuya Nishihara <yuya@tcha.org>
parents: 36791
diff changeset
   351
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   352
36793
eca1051e6c22 util: add public isstdin/isstdout() functions
Yuya Nishihara <yuya@tcha.org>
parents: 36791
diff changeset
   353
def isstdout(f):
eca1051e6c22 util: add public isstdin/isstdout() functions
Yuya Nishihara <yuya@tcha.org>
parents: 36791
diff changeset
   354
    return _testfileno(f, sys.__stdout__)
eca1051e6c22 util: add public isstdin/isstdout() functions
Yuya Nishihara <yuya@tcha.org>
parents: 36791
diff changeset
   355
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   356
37123
0216232f21ab procutil: move protectio/restoreio from commandserver
Yuya Nishihara <yuya@tcha.org>
parents: 37118
diff changeset
   357
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
   358
    """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
   359
7f78de1c93aa procutil: redirect ui.fout to stderr while stdio is protected
Yuya Nishihara <yuya@tcha.org>
parents: 37219
diff changeset
   360
    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
   361
    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
   362
0216232f21ab procutil: move protectio/restoreio from commandserver
Yuya Nishihara <yuya@tcha.org>
parents: 37118
diff changeset
   363
    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
   364
    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
   365
    "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
   366
    """
0216232f21ab procutil: move protectio/restoreio from commandserver
Yuya Nishihara <yuya@tcha.org>
parents: 37118
diff changeset
   367
    uout.flush()
37219
ac71cbad5da3 procutil: unroll uin/uout loop in protectstdio()
Yuya Nishihara <yuya@tcha.org>
parents: 37124
diff changeset
   368
    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
   369
    if _testfileno(uin, stdin):
37219
ac71cbad5da3 procutil: unroll uin/uout loop in protectstdio()
Yuya Nishihara <yuya@tcha.org>
parents: 37124
diff changeset
   370
        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
   371
        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
   372
        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
   373
        os.close(nullfd)
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43503
diff changeset
   374
        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
   375
    if _testfileno(uout, stdout):
37219
ac71cbad5da3 procutil: unroll uin/uout loop in protectstdio()
Yuya Nishihara <yuya@tcha.org>
parents: 37124
diff changeset
   376
        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
   377
        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
   378
        fout = os.fdopen(newfd, 'wb')
37219
ac71cbad5da3 procutil: unroll uin/uout loop in protectstdio()
Yuya Nishihara <yuya@tcha.org>
parents: 37124
diff changeset
   379
    return fin, fout
37123
0216232f21ab procutil: move protectio/restoreio from commandserver
Yuya Nishihara <yuya@tcha.org>
parents: 37118
diff changeset
   380
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   381
37123
0216232f21ab procutil: move protectio/restoreio from commandserver
Yuya Nishihara <yuya@tcha.org>
parents: 37118
diff changeset
   382
def restorestdio(uin, uout, fin, fout):
0216232f21ab procutil: move protectio/restoreio from commandserver
Yuya Nishihara <yuya@tcha.org>
parents: 37118
diff changeset
   383
    """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
   384
    uout.flush()
0216232f21ab procutil: move protectio/restoreio from commandserver
Yuya Nishihara <yuya@tcha.org>
parents: 37118
diff changeset
   385
    for f, uif in [(fin, uin), (fout, uout)]:
0216232f21ab procutil: move protectio/restoreio from commandserver
Yuya Nishihara <yuya@tcha.org>
parents: 37118
diff changeset
   386
        if f is not uif:
0216232f21ab procutil: move protectio/restoreio from commandserver
Yuya Nishihara <yuya@tcha.org>
parents: 37118
diff changeset
   387
            os.dup2(f.fileno(), uif.fileno())
0216232f21ab procutil: move protectio/restoreio from commandserver
Yuya Nishihara <yuya@tcha.org>
parents: 37118
diff changeset
   388
            f.close()
0216232f21ab procutil: move protectio/restoreio from commandserver
Yuya Nishihara <yuya@tcha.org>
parents: 37118
diff changeset
   389
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   390
30736
d9e5b0aeeb90 util: extract the logic calculating environment variables
Jun Wu <quark@fb.com>
parents: 30669
diff changeset
   391
def shellenviron(environ=None):
d9e5b0aeeb90 util: extract the logic calculating environment variables
Jun Wu <quark@fb.com>
parents: 30669
diff changeset
   392
    """return environ with optional override, useful for shelling out"""
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   393
30736
d9e5b0aeeb90 util: extract the logic calculating environment variables
Jun Wu <quark@fb.com>
parents: 30669
diff changeset
   394
    def py2shell(val):
43787
be8552f25cab cleanup: fix docstring formatting
Matt Harbison <matt_harbison@yahoo.com>
parents: 43671
diff changeset
   395
        """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
   396
        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
   397
            return b'0'
30736
d9e5b0aeeb90 util: extract the logic calculating environment variables
Jun Wu <quark@fb.com>
parents: 30669
diff changeset
   398
        if val is True:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   399
            return b'1'
36418
d26b0bedfaa4 util: use pycompat.bytestr() instead of str()
Augie Fackler <augie@google.com>
parents: 36415
diff changeset
   400
        return pycompat.bytestr(val)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   401
30736
d9e5b0aeeb90 util: extract the logic calculating environment variables
Jun Wu <quark@fb.com>
parents: 30669
diff changeset
   402
    env = dict(encoding.environ)
d9e5b0aeeb90 util: extract the logic calculating environment variables
Jun Wu <quark@fb.com>
parents: 30669
diff changeset
   403
    if environ:
43106
d783f945a701 py3: finish porting iteritems() to pycompat and remove source transformer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43096
diff changeset
   404
        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
   405
    env[b'HG'] = hgexecutable()
30736
d9e5b0aeeb90 util: extract the logic calculating environment variables
Jun Wu <quark@fb.com>
parents: 30669
diff changeset
   406
    return env
d9e5b0aeeb90 util: extract the logic calculating environment variables
Jun Wu <quark@fb.com>
parents: 30669
diff changeset
   407
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   408
38491
72286f9e324f procutil: add a shim for translating shell commands to native commands
Matt Harbison <matt_harbison@yahoo.com>
parents: 38454
diff changeset
   409
if pycompat.iswindows:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   410
38491
72286f9e324f procutil: add a shim for translating shell commands to native commands
Matt Harbison <matt_harbison@yahoo.com>
parents: 38454
diff changeset
   411
    def shelltonative(cmd, env):
43478
54f4d094bab1 procutil: suppress pytype warnings around windows-only attributes
Augie Fackler <augie@google.com>
parents: 43165
diff changeset
   412
        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
   413
            cmd, shellenviron(env)
54f4d094bab1 procutil: suppress pytype warnings around windows-only attributes
Augie Fackler <augie@google.com>
parents: 43165
diff changeset
   414
        )
39662
50f46b771921 py3: partially fix pager spawning on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 38526
diff changeset
   415
50f46b771921 py3: partially fix pager spawning on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 38526
diff changeset
   416
    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
   417
else:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   418
38491
72286f9e324f procutil: add a shim for translating shell commands to native commands
Matt Harbison <matt_harbison@yahoo.com>
parents: 38454
diff changeset
   419
    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
   420
        return cmd
72286f9e324f procutil: add a shim for translating shell commands to native commands
Matt Harbison <matt_harbison@yahoo.com>
parents: 38454
diff changeset
   421
39662
50f46b771921 py3: partially fix pager spawning on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 38526
diff changeset
   422
    tonativestr = pycompat.identity
50f46b771921 py3: partially fix pager spawning on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 38526
diff changeset
   423
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   424
39662
50f46b771921 py3: partially fix pager spawning on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 38526
diff changeset
   425
def tonativeenv(env):
50f46b771921 py3: partially fix pager spawning on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 38526
diff changeset
   426
    '''convert the environment from bytes to strings suitable for Popen(), etc.
50f46b771921 py3: partially fix pager spawning on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 38526
diff changeset
   427
    '''
50f46b771921 py3: partially fix pager spawning on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 38526
diff changeset
   428
    return pycompat.rapply(tonativestr, env)
50f46b771921 py3: partially fix pager spawning on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 38526
diff changeset
   429
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   430
31108
3f8f53190d6a chg: deduplicate error handling of ui.system()
Yuya Nishihara <yuya@tcha.org>
parents: 31074
diff changeset
   431
def system(cmd, environ=None, cwd=None, out=None):
1882
c0320567931f merge util.esystem and util.system.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1880
diff changeset
   432
    '''enhanced shell command execution.
c0320567931f merge util.esystem and util.system.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1880
diff changeset
   433
    run with environment maybe modified, maybe in different dir.
508
42a660abaf75 [PATCH] Harden os.system
mpm@selenic.com
parents: 464
diff changeset
   434
11469
c37f35d7f2f5 http: deliver hook output to client
Maxim Khitrov <mkhitrov@gmail.com>
parents: 11297
diff changeset
   435
    if out is specified, it is assumed to be a file-like object that has a
c37f35d7f2f5 http: deliver hook output to client
Maxim Khitrov <mkhitrov@gmail.com>
parents: 11297
diff changeset
   436
    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
   437
    try:
30473
39d13b8c101d py3: bulk replace sys.stdin/out/err by util's
Yuya Nishihara <yuya@tcha.org>
parents: 30472
diff changeset
   438
        stdout.flush()
13439
d724a69309e0 util: flush stdout before calling external processes
Mads Kiilerich <mads@kiilerich.com>
parents: 13400
diff changeset
   439
    except Exception:
d724a69309e0 util: flush stdout before calling external processes
Mads Kiilerich <mads@kiilerich.com>
parents: 13400
diff changeset
   440
        pass
32886
19b0fd4b5570 plan9: drop py26 hacks
Matt Harbison <matt_harbison@yahoo.com>
parents: 32816
diff changeset
   441
    env = shellenviron(environ)
36793
eca1051e6c22 util: add public isstdin/isstdout() functions
Yuya Nishihara <yuya@tcha.org>
parents: 36791
diff changeset
   442
    if out is None or isstdout(out):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   443
        rc = subprocess.call(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   444
            tonativestr(cmd),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   445
            shell=True,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   446
            close_fds=closefds,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   447
            env=tonativeenv(env),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   448
            cwd=pycompat.rapply(tonativestr, cwd),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   449
        )
11469
c37f35d7f2f5 http: deliver hook output to client
Maxim Khitrov <mkhitrov@gmail.com>
parents: 11297
diff changeset
   450
    else:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   451
        proc = subprocess.Popen(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   452
            tonativestr(cmd),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   453
            shell=True,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   454
            close_fds=closefds,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   455
            env=tonativeenv(env),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   456
            cwd=pycompat.rapply(tonativestr, cwd),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   457
            stdout=subprocess.PIPE,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   458
            stderr=subprocess.STDOUT,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   459
        )
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   460
        for line in iter(proc.stdout.readline, b''):
32886
19b0fd4b5570 plan9: drop py26 hacks
Matt Harbison <matt_harbison@yahoo.com>
parents: 32816
diff changeset
   461
            out.write(line)
19b0fd4b5570 plan9: drop py26 hacks
Matt Harbison <matt_harbison@yahoo.com>
parents: 32816
diff changeset
   462
        proc.wait()
19b0fd4b5570 plan9: drop py26 hacks
Matt Harbison <matt_harbison@yahoo.com>
parents: 32816
diff changeset
   463
        rc = proc.returncode
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   464
    if pycompat.sysplatform == b'OpenVMS' and rc & 1:
32886
19b0fd4b5570 plan9: drop py26 hacks
Matt Harbison <matt_harbison@yahoo.com>
parents: 32816
diff changeset
   465
        rc = 0
9517
4368f582c806 util.system: Use subprocess instead of os.system
Mads Kiilerich <mads@kiilerich.com>
parents: 9508
diff changeset
   466
    return rc
1880
05c7d75be925 fix broken environment save/restore when a hook runs.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1877
diff changeset
   467
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   468
43912
a89381e04c58 procutil: try and avoid angering CoreFoundation on macOS
Augie Fackler <augie@google.com>
parents: 43862
diff changeset
   469
_is_gui = None
a89381e04c58 procutil: try and avoid angering CoreFoundation on macOS
Augie Fackler <augie@google.com>
parents: 43862
diff changeset
   470
a89381e04c58 procutil: try and avoid angering CoreFoundation on macOS
Augie Fackler <augie@google.com>
parents: 43862
diff changeset
   471
a89381e04c58 procutil: try and avoid angering CoreFoundation on macOS
Augie Fackler <augie@google.com>
parents: 43862
diff changeset
   472
def _gui():
6007
090b1a665901 filemerge: add config item for GUI tools
Matt Mackall <mpm@selenic.com>
parents: 6006
diff changeset
   473
    '''Are we running in a GUI?'''
34647
dacfcdd8b94e codemod: use pycompat.isdarwin
Jun Wu <quark@fb.com>
parents: 34646
diff changeset
   474
    if pycompat.isdarwin:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   475
        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
   476
            # 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
   477
            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
   478
        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
   479
            # 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
   480
            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
   481
        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
   482
            # 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
   483
            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
   484
    else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   485
        return pycompat.iswindows or encoding.environ.get(b"DISPLAY")
6007
090b1a665901 filemerge: add config item for GUI tools
Matt Mackall <mpm@selenic.com>
parents: 6006
diff changeset
   486
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   487
43912
a89381e04c58 procutil: try and avoid angering CoreFoundation on macOS
Augie Fackler <augie@google.com>
parents: 43862
diff changeset
   488
def gui():
a89381e04c58 procutil: try and avoid angering CoreFoundation on macOS
Augie Fackler <augie@google.com>
parents: 43862
diff changeset
   489
    global _is_gui
a89381e04c58 procutil: try and avoid angering CoreFoundation on macOS
Augie Fackler <augie@google.com>
parents: 43862
diff changeset
   490
    if _is_gui is None:
a89381e04c58 procutil: try and avoid angering CoreFoundation on macOS
Augie Fackler <augie@google.com>
parents: 43862
diff changeset
   491
        _is_gui = _gui()
a89381e04c58 procutil: try and avoid angering CoreFoundation on macOS
Augie Fackler <augie@google.com>
parents: 43862
diff changeset
   492
    return _is_gui
a89381e04c58 procutil: try and avoid angering CoreFoundation on macOS
Augie Fackler <augie@google.com>
parents: 43862
diff changeset
   493
a89381e04c58 procutil: try and avoid angering CoreFoundation on macOS
Augie Fackler <augie@google.com>
parents: 43862
diff changeset
   494
10239
8e4be44a676f Find right hg command for detached process
Patrick Mezard <pmezard@gmail.com>
parents: 10199
diff changeset
   495
def hgcmd():
8e4be44a676f Find right hg command for detached process
Patrick Mezard <pmezard@gmail.com>
parents: 10199
diff changeset
   496
    """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
   497
8e4be44a676f Find right hg command for detached process
Patrick Mezard <pmezard@gmail.com>
parents: 10199
diff changeset
   498
    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
   499
    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
   500
    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
   501
    """
43671
664e24207728 procutil: move mainfrozen() to new resourceutil.py
Martin von Zweigbergk <martinvonz@google.com>
parents: 43657
diff changeset
   502
    if resourceutil.mainfrozen():
43657
38387f9e4d22 py3: use native string for 'macosx_app'
Martin von Zweigbergk <martinvonz@google.com>
parents: 43656
diff changeset
   503
        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
   504
            # Env variable set by py2app
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   505
            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
   506
        else:
30669
10b17ed9b591 py3: replace sys.executable with pycompat.sysexecutable
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30642
diff changeset
   507
            return [pycompat.sysexecutable]
37115
49d6ba67c93f util: mark platform-specific gethgcmd() as private
Yuya Nishihara <yuya@tcha.org>
parents: 37099
diff changeset
   508
    return _gethgcmd()
10344
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   509
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   510
10344
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   511
def rundetached(args, condfn):
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   512
    """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
   513
10344
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   514
    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
   515
    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
   516
    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
   517
    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
   518
    True, return -1.
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   519
    """
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   520
    # 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
   521
    # 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
   522
    # 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
   523
    # 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
   524
    # 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
   525
    # 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
   526
    # us our child process terminated.
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   527
    terminated = set()
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   528
10344
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   529
    def handler(signum, frame):
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   530
        terminated.add(os.wait())
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   531
10344
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   532
    prevhandler = None
14968
b7dbe957585c util: use safehasattr or getattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents: 14942
diff changeset
   533
    SIGCHLD = getattr(signal, 'SIGCHLD', None)
b7dbe957585c util: use safehasattr or getattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents: 14942
diff changeset
   534
    if SIGCHLD is not None:
b7dbe957585c util: use safehasattr or getattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents: 14942
diff changeset
   535
        prevhandler = signal.signal(SIGCHLD, handler)
10344
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   536
    try:
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   537
        pid = spawndetached(args)
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   538
        while not condfn():
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   539
            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
   540
                return -1
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   541
            time.sleep(0.1)
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   542
        return pid
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   543
    finally:
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   544
        if prevhandler is not None:
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   545
            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
   546
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   547
38526
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   548
@contextlib.contextmanager
41076
8ecb17b7f432 procutil: correct spelling of uninterruptable -> uninterruptible
Kyle Lippincott <spectral@google.com>
parents: 40712
diff changeset
   549
def uninterruptible(warn):
38526
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   550
    """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
   551
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   552
    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
   553
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   554
    Args:
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   555
      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
   556
            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
   557
    """
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   558
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   559
    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
   560
    shouldbail = []
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   561
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   562
    def disabledsiginthandler(*args):
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   563
        if warn():
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   564
            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
   565
            del oldsiginthandler[0]
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   566
        shouldbail.append(True)
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   567
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   568
    try:
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   569
        try:
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   570
            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
   571
        except ValueError:
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   572
            # 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
   573
            del oldsiginthandler[0]
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   574
        yield
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   575
    finally:
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   576
        if oldsiginthandler:
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   577
            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
   578
        if shouldbail:
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38525
diff changeset
   579
            raise KeyboardInterrupt
40497
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   580
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   581
40497
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   582
if pycompat.iswindows:
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   583
    # 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
   584
    # 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
   585
    # No stdlib constant exists for this value
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   586
    DETACHED_PROCESS = 0x00000008
40536
1d3bed7d2923 procutil: import concerns about creationflags on Windows from D1701
Boris Feld <boris.feld@octobus.net>
parents: 40498
diff changeset
   587
    # 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
   588
    # 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
   589
    # 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
   590
    _creationflags = (
54f4d094bab1 procutil: suppress pytype warnings around windows-only attributes
Augie Fackler <augie@google.com>
parents: 43165
diff changeset
   591
        DETACHED_PROCESS
54f4d094bab1 procutil: suppress pytype warnings around windows-only attributes
Augie Fackler <augie@google.com>
parents: 43165
diff changeset
   592
        | 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
   593
    )
40497
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   594
42496
ca1014ad3de4 procutil: allow callers of runbgcommand to assume the process starts
Augie Fackler <augie@google.com>
parents: 41832
diff changeset
   595
    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
   596
        script,
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   597
        env,
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   598
        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
   599
        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
   600
        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
   601
        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
   602
        record_wait=None,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   603
    ):
40497
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   604
        '''Spawn a command without waiting for it to finish.'''
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   605
        # 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
   606
        # need to because the detached process has no console connection.
43848
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   607
        p = subprocess.Popen(
40498
8fab95aa5280 procutil: port over windows encoding fixes from logtoprocess
Augie Fackler <augie@google.com>
parents: 40497
diff changeset
   608
            tonativestr(script),
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   609
            shell=shell,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   610
            env=tonativeenv(env),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   611
            close_fds=True,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   612
            creationflags=_creationflags,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   613
            stdout=stdout,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   614
            stderr=stderr,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   615
        )
43848
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   616
        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
   617
            record_wait(p.wait)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   618
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   619
40497
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   620
else:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   621
42496
ca1014ad3de4 procutil: allow callers of runbgcommand to assume the process starts
Augie Fackler <augie@google.com>
parents: 41832
diff changeset
   622
    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
   623
        cmd,
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   624
        env,
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   625
        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
   626
        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
   627
        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
   628
        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
   629
        record_wait=None,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   630
    ):
43848
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   631
        '''Spawn a command without waiting for it to finish.
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   632
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   633
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   634
        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
   635
        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
   636
        `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
   637
        useful for developers that need to make sure the spawned process
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   638
        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
   639
        if pycompat.isdarwin:
a89381e04c58 procutil: try and avoid angering CoreFoundation on macOS
Augie Fackler <augie@google.com>
parents: 43862
diff changeset
   640
            # 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
   641
            # 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
   642
            gui()
a89381e04c58 procutil: try and avoid angering CoreFoundation on macOS
Augie Fackler <augie@google.com>
parents: 43862
diff changeset
   643
40497
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   644
        # double-fork to completely detach from the parent process
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   645
        # 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
   646
        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
   647
            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
   648
            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
   649
                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
   650
                    # 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
   651
                    # 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
   652
                    # 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
   653
                    # 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
   654
                    # 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
   655
                    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
   656
                        os.waitpid(pid, 0)
44812
79f6f856c53f formatting: add missing newline
Raphaël Gomès <rgomes@octobus.net>
parents: 44781
diff changeset
   657
44978
95c672c07116 procutil: make recent fix for zombies compatible with py2
Martin von Zweigbergk <martinvonz@google.com>
parents: 44919
diff changeset
   658
                    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
   659
                    t.daemon = True
95c672c07116 procutil: make recent fix for zombies compatible with py2
Martin von Zweigbergk <martinvonz@google.com>
parents: 44919
diff changeset
   660
                    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
   661
                    return
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   662
                # 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
   663
                (_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
   664
                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
   665
                    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
   666
                else:
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   667
                    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
   668
                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
   669
                    # 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
   670
                    # 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
   671
                    # value.
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   672
                    #
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   673
                    # (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
   674
                    # 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
   675
                    # 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
   676
                    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
   677
                        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
   678
                    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
   679
                        returncode,
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   680
                        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
   681
                        % (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
   682
                    )
42496
ca1014ad3de4 procutil: allow callers of runbgcommand to assume the process starts
Augie Fackler <augie@google.com>
parents: 41832
diff changeset
   683
                return
40497
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   684
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   685
        returncode = 255
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   686
        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
   687
            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
   688
                # 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
   689
                os.setsid()
40497
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   690
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   691
            stdin = open(os.devnull, b'r')
40497
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   692
            if stdout is None:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   693
                stdout = open(os.devnull, b'w')
40497
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   694
            if stderr is None:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   695
                stderr = open(os.devnull, b'w')
40497
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   696
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   697
            # connect stdin to devnull to make sure the subprocess can't
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   698
            # muck up that stream for mercurial.
43848
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   699
            p = subprocess.Popen(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   700
                cmd,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   701
                shell=shell,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   702
                env=env,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   703
                close_fds=True,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   704
                stdin=stdin,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   705
                stdout=stdout,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   706
                stderr=stderr,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   707
            )
43848
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   708
            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
   709
                record_wait(p.wait)
40497
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   710
            returncode = 0
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   711
        except EnvironmentError as ex:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
   712
            returncode = ex.errno & 0xFF
40497
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   713
            if returncode == 0:
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   714
                # 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
   715
                # return code is never 0 here.
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   716
                returncode = 255
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   717
        except Exception:
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   718
            returncode = 255
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   719
        finally:
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   720
            # mission accomplished, this child needs to exit and not
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39840
diff changeset
   721
            # continue the hg process here.
43848
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
   722
            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
   723
                os._exit(returncode)