annotate mercurial/utils/procutil.py @ 46174:a1601ff3877c

procutil: introduce pseudo file object that just raises EBADF This should be safer than closing underlying fd as the fd may be reused. On Python 2, closed sys.stdin could be redirected to a random file having fd=0, but we'd be better not copying this behavior. Only readinto() and write() are implemented according to the following ABC table. fileno() is not implemented since fd=0/1/2 may be assigned later to other files. https://docs.python.org/3/library/io.html#class-hierarchy
author Yuya Nishihara <yuya@tcha.org>
date Sat, 19 Dec 2020 11:10:18 +0900
parents 7ce24d3761e8
children a04c03b0678e
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
37121
5be286db5fb5 procutil: move process/executable management functions to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37120
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
37121
5be286db5fb5 procutil: move process/executable management functions to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37120
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
37127
6715e8035b4f procutil: introduce context-manager interface for protect/restorestdio
Yuya Nishihara <yuya@tcha.org>
parents: 37126
diff changeset
12 import contextlib
40547
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39845
diff changeset
13 import errno
36462
1ca4e86c7265 util: handle fileno() on Python 3 throwing io.UnsupportedOperation
Augie Fackler <augie@google.com>
parents: 36452
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
44764
ed684a82e29b procutil: always waiting on child processes to prevent zombies with 'hg serve'
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 43918
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
37121
5be286db5fb5 procutil: move process/executable management functions to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37120
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 )
37121
5be286db5fb5 procutil: move process/executable management functions to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37120
diff changeset
27
5be286db5fb5 procutil: move process/executable management functions to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37120
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,
32406
a9c71d578a1c osutil: switch to policy importer
Yuya Nishihara <yuya@tcha.org>
parents: 32346
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,
37086
f99d64e8a4e4 stringutil: move generic string helpers to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37085
diff changeset
33 )
3769
96095d9ff1f8 Add encoding detection
Matt Mackall <mpm@selenic.com>
parents: 3767
diff changeset
34
43712
664e24207728 procutil: move mainfrozen() to new resourceutil.py
Martin von Zweigbergk <martinvonz@google.com>
parents: 43701
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: 43701
diff changeset
36 from ..utils import resourceutil
664e24207728 procutil: move mainfrozen() to new resourceutil.py
Martin von Zweigbergk <martinvonz@google.com>
parents: 43701
diff changeset
37
43554
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43551
diff changeset
38 osutil = policy.importmod('osutil')
32245
4462a981e8df base85: proxy through util module
Yuya Nishihara <yuya@tcha.org>
parents: 32203
diff changeset
39
45045
c88577199023 procutil: split import and reassignment
Manuel Jacob <me@manueljacob.de>
parents: 45044
diff changeset
40 if pycompat.iswindows:
c88577199023 procutil: split import and reassignment
Manuel Jacob <me@manueljacob.de>
parents: 45044
diff changeset
41 from .. import windows as platform
c88577199023 procutil: split import and reassignment
Manuel Jacob <me@manueljacob.de>
parents: 45044
diff changeset
42 else:
c88577199023 procutil: split import and reassignment
Manuel Jacob <me@manueljacob.de>
parents: 45044
diff changeset
43 from .. import posix as platform
c88577199023 procutil: split import and reassignment
Manuel Jacob <me@manueljacob.de>
parents: 45044
diff changeset
44
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
45
30908
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: 43021
diff changeset
52
46174
a1601ff3877c procutil: introduce pseudo file object that just raises EBADF
Yuya Nishihara <yuya@tcha.org>
parents: 46103
diff changeset
53 class BadFile(io.RawIOBase):
a1601ff3877c procutil: introduce pseudo file object that just raises EBADF
Yuya Nishihara <yuya@tcha.org>
parents: 46103
diff changeset
54 """Dummy file object to simulate closed stdio behavior"""
a1601ff3877c procutil: introduce pseudo file object that just raises EBADF
Yuya Nishihara <yuya@tcha.org>
parents: 46103
diff changeset
55
a1601ff3877c procutil: introduce pseudo file object that just raises EBADF
Yuya Nishihara <yuya@tcha.org>
parents: 46103
diff changeset
56 def readinto(self, b):
a1601ff3877c procutil: introduce pseudo file object that just raises EBADF
Yuya Nishihara <yuya@tcha.org>
parents: 46103
diff changeset
57 raise IOError(errno.EBADF, 'Bad file descriptor')
a1601ff3877c procutil: introduce pseudo file object that just raises EBADF
Yuya Nishihara <yuya@tcha.org>
parents: 46103
diff changeset
58
a1601ff3877c procutil: introduce pseudo file object that just raises EBADF
Yuya Nishihara <yuya@tcha.org>
parents: 46103
diff changeset
59 def write(self, b):
a1601ff3877c procutil: introduce pseudo file object that just raises EBADF
Yuya Nishihara <yuya@tcha.org>
parents: 46103
diff changeset
60 raise IOError(errno.EBADF, 'Bad file descriptor')
a1601ff3877c procutil: introduce pseudo file object that just raises EBADF
Yuya Nishihara <yuya@tcha.org>
parents: 46103
diff changeset
61
a1601ff3877c procutil: introduce pseudo file object that just raises EBADF
Yuya Nishihara <yuya@tcha.org>
parents: 46103
diff changeset
62
45042
2bfbd7d2c204 procutil: define LineBufferedWrapper on all Python versions
Manuel Jacob <me@manueljacob.de>
parents: 45020
diff changeset
63 class LineBufferedWrapper(object):
2bfbd7d2c204 procutil: define LineBufferedWrapper on all Python versions
Manuel Jacob <me@manueljacob.de>
parents: 45020
diff changeset
64 def __init__(self, orig):
2bfbd7d2c204 procutil: define LineBufferedWrapper on all Python versions
Manuel Jacob <me@manueljacob.de>
parents: 45020
diff changeset
65 self.orig = orig
44991
f9734b2d59cc py3: make stdout line-buffered if connected to a TTY
Manuel Jacob <me@manueljacob.de>
parents: 44926
diff changeset
66
45042
2bfbd7d2c204 procutil: define LineBufferedWrapper on all Python versions
Manuel Jacob <me@manueljacob.de>
parents: 45020
diff changeset
67 def __getattr__(self, attr):
2bfbd7d2c204 procutil: define LineBufferedWrapper on all Python versions
Manuel Jacob <me@manueljacob.de>
parents: 45020
diff changeset
68 return getattr(self.orig, attr)
44991
f9734b2d59cc py3: make stdout line-buffered if connected to a TTY
Manuel Jacob <me@manueljacob.de>
parents: 44926
diff changeset
69
45042
2bfbd7d2c204 procutil: define LineBufferedWrapper on all Python versions
Manuel Jacob <me@manueljacob.de>
parents: 45020
diff changeset
70 def write(self, s):
2bfbd7d2c204 procutil: define LineBufferedWrapper on all Python versions
Manuel Jacob <me@manueljacob.de>
parents: 45020
diff changeset
71 orig = self.orig
2bfbd7d2c204 procutil: define LineBufferedWrapper on all Python versions
Manuel Jacob <me@manueljacob.de>
parents: 45020
diff changeset
72 res = orig.write(s)
2bfbd7d2c204 procutil: define LineBufferedWrapper on all Python versions
Manuel Jacob <me@manueljacob.de>
parents: 45020
diff changeset
73 if s.endswith(b'\n'):
2bfbd7d2c204 procutil: define LineBufferedWrapper on all Python versions
Manuel Jacob <me@manueljacob.de>
parents: 45020
diff changeset
74 orig.flush()
2bfbd7d2c204 procutil: define LineBufferedWrapper on all Python versions
Manuel Jacob <me@manueljacob.de>
parents: 45020
diff changeset
75 return res
44991
f9734b2d59cc py3: make stdout line-buffered if connected to a TTY
Manuel Jacob <me@manueljacob.de>
parents: 44926
diff changeset
76
45042
2bfbd7d2c204 procutil: define LineBufferedWrapper on all Python versions
Manuel Jacob <me@manueljacob.de>
parents: 45020
diff changeset
77
2bfbd7d2c204 procutil: define LineBufferedWrapper on all Python versions
Manuel Jacob <me@manueljacob.de>
parents: 45020
diff changeset
78 io.BufferedIOBase.register(LineBufferedWrapper)
44991
f9734b2d59cc py3: make stdout line-buffered if connected to a TTY
Manuel Jacob <me@manueljacob.de>
parents: 44926
diff changeset
79
f9734b2d59cc py3: make stdout line-buffered if connected to a TTY
Manuel Jacob <me@manueljacob.de>
parents: 44926
diff changeset
80
45043
fd205a9c358a procutil: factor out conditional creation of LineBufferedWrapper
Manuel Jacob <me@manueljacob.de>
parents: 45042
diff changeset
81 def make_line_buffered(stream):
fd205a9c358a procutil: factor out conditional creation of LineBufferedWrapper
Manuel Jacob <me@manueljacob.de>
parents: 45042
diff changeset
82 if pycompat.ispy3 and not isinstance(stream, io.BufferedIOBase):
fd205a9c358a procutil: factor out conditional creation of LineBufferedWrapper
Manuel Jacob <me@manueljacob.de>
parents: 45042
diff changeset
83 # On Python 3, buffered streams can be expected to subclass
fd205a9c358a procutil: factor out conditional creation of LineBufferedWrapper
Manuel Jacob <me@manueljacob.de>
parents: 45042
diff changeset
84 # BufferedIOBase. This is definitively the case for the streams
fd205a9c358a procutil: factor out conditional creation of LineBufferedWrapper
Manuel Jacob <me@manueljacob.de>
parents: 45042
diff changeset
85 # initialized by the interpreter. For unbuffered streams, we don't need
fd205a9c358a procutil: factor out conditional creation of LineBufferedWrapper
Manuel Jacob <me@manueljacob.de>
parents: 45042
diff changeset
86 # to emulate line buffering.
fd205a9c358a procutil: factor out conditional creation of LineBufferedWrapper
Manuel Jacob <me@manueljacob.de>
parents: 45042
diff changeset
87 return stream
fd205a9c358a procutil: factor out conditional creation of LineBufferedWrapper
Manuel Jacob <me@manueljacob.de>
parents: 45042
diff changeset
88 if isinstance(stream, LineBufferedWrapper):
fd205a9c358a procutil: factor out conditional creation of LineBufferedWrapper
Manuel Jacob <me@manueljacob.de>
parents: 45042
diff changeset
89 return stream
fd205a9c358a procutil: factor out conditional creation of LineBufferedWrapper
Manuel Jacob <me@manueljacob.de>
parents: 45042
diff changeset
90 return LineBufferedWrapper(stream)
fd205a9c358a procutil: factor out conditional creation of LineBufferedWrapper
Manuel Jacob <me@manueljacob.de>
parents: 45042
diff changeset
91
fd205a9c358a procutil: factor out conditional creation of LineBufferedWrapper
Manuel Jacob <me@manueljacob.de>
parents: 45042
diff changeset
92
45867
b56feaa9b520 chgserver: backport py3 buffered I/O workarounds from procutil
Yuya Nishihara <yuya@tcha.org>
parents: 45809
diff changeset
93 def unwrap_line_buffered(stream):
b56feaa9b520 chgserver: backport py3 buffered I/O workarounds from procutil
Yuya Nishihara <yuya@tcha.org>
parents: 45809
diff changeset
94 if isinstance(stream, LineBufferedWrapper):
b56feaa9b520 chgserver: backport py3 buffered I/O workarounds from procutil
Yuya Nishihara <yuya@tcha.org>
parents: 45809
diff changeset
95 assert not isinstance(stream.orig, LineBufferedWrapper)
b56feaa9b520 chgserver: backport py3 buffered I/O workarounds from procutil
Yuya Nishihara <yuya@tcha.org>
parents: 45809
diff changeset
96 return stream.orig
b56feaa9b520 chgserver: backport py3 buffered I/O workarounds from procutil
Yuya Nishihara <yuya@tcha.org>
parents: 45809
diff changeset
97 return stream
b56feaa9b520 chgserver: backport py3 buffered I/O workarounds from procutil
Yuya Nishihara <yuya@tcha.org>
parents: 45809
diff changeset
98
b56feaa9b520 chgserver: backport py3 buffered I/O workarounds from procutil
Yuya Nishihara <yuya@tcha.org>
parents: 45809
diff changeset
99
45095
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
100 class WriteAllWrapper(object):
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
101 def __init__(self, orig):
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
102 self.orig = orig
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
103
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
104 def __getattr__(self, attr):
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
105 return getattr(self.orig, attr)
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
106
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
107 def write(self, s):
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
108 write1 = self.orig.write
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
109 m = memoryview(s)
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
110 total_to_write = len(s)
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
111 total_written = 0
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
112 while total_written < total_to_write:
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
113 total_written += write1(m[total_written:])
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
114 return total_written
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
115
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
116
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
117 io.IOBase.register(WriteAllWrapper)
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
118
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
119
45103
a5fa2761a6cd procutil: make _make_write_all() function private
Manuel Jacob <me@manueljacob.de>
parents: 45095
diff changeset
120 def _make_write_all(stream):
45095
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
121 assert pycompat.ispy3
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
122 if isinstance(stream, WriteAllWrapper):
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
123 return stream
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
124 if isinstance(stream, io.BufferedIOBase):
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
125 # The io.BufferedIOBase.write() contract guarantees that all data is
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
126 # written.
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
127 return stream
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
128 # In general, the write() method of streams is free to write only part of
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
129 # the data.
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
130 return WriteAllWrapper(stream)
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
131
8e04607023e5 procutil: ensure that procutil.std{out,err}.write() writes all bytes
Manuel Jacob <me@manueljacob.de>
parents: 45094
diff changeset
132
45057
9694895749ad pycompat: remove pycompat.{stdin,stdout,stderr}
Manuel Jacob <me@manueljacob.de>
parents: 45048
diff changeset
133 if pycompat.ispy3:
45093
63196198dbf0 procutil: distribute code for stdout
Manuel Jacob <me@manueljacob.de>
parents: 45083
diff changeset
134 # Python 3 implements its own I/O streams.
45057
9694895749ad pycompat: remove pycompat.{stdin,stdout,stderr}
Manuel Jacob <me@manueljacob.de>
parents: 45048
diff changeset
135 # TODO: .buffer might not exist if std streams were replaced; we'll need
9694895749ad pycompat: remove pycompat.{stdin,stdout,stderr}
Manuel Jacob <me@manueljacob.de>
parents: 45048
diff changeset
136 # a silly wrapper to make a bytes stream backed by a unicode one.
46084
81c1f5d1801f procutils: don't try to get `.buffer` if sys.stdin is None
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46034
diff changeset
137
81c1f5d1801f procutils: don't try to get `.buffer` if sys.stdin is None
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46034
diff changeset
138 # sys.stdin can be None
46103
7ce24d3761e8 procutil: don't assign stdin to None, use os.devnull instead
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46084
diff changeset
139 if sys.stdin:
7ce24d3761e8 procutil: don't assign stdin to None, use os.devnull instead
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46084
diff changeset
140 stdin = sys.stdin.buffer
7ce24d3761e8 procutil: don't assign stdin to None, use os.devnull instead
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46084
diff changeset
141 else:
46174
a1601ff3877c procutil: introduce pseudo file object that just raises EBADF
Yuya Nishihara <yuya@tcha.org>
parents: 46103
diff changeset
142 stdin = BadFile()
45103
a5fa2761a6cd procutil: make _make_write_all() function private
Manuel Jacob <me@manueljacob.de>
parents: 45095
diff changeset
143 stdout = _make_write_all(sys.stdout.buffer)
45148
a37f290a7124 windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents: 45103
diff changeset
144 stderr = _make_write_all(sys.stderr.buffer)
a37f290a7124 windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents: 45103
diff changeset
145 if pycompat.iswindows:
a37f290a7124 windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents: 45103
diff changeset
146 # Work around Windows bugs.
a37f290a7124 windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents: 45103
diff changeset
147 stdout = platform.winstdout(stdout)
a37f290a7124 windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents: 45103
diff changeset
148 stderr = platform.winstdout(stderr)
45093
63196198dbf0 procutil: distribute code for stdout
Manuel Jacob <me@manueljacob.de>
parents: 45083
diff changeset
149 if isatty(stdout):
63196198dbf0 procutil: distribute code for stdout
Manuel Jacob <me@manueljacob.de>
parents: 45083
diff changeset
150 # The standard library doesn't offer line-buffered binary streams.
63196198dbf0 procutil: distribute code for stdout
Manuel Jacob <me@manueljacob.de>
parents: 45083
diff changeset
151 stdout = make_line_buffered(stdout)
45057
9694895749ad pycompat: remove pycompat.{stdin,stdout,stderr}
Manuel Jacob <me@manueljacob.de>
parents: 45048
diff changeset
152 else:
45093
63196198dbf0 procutil: distribute code for stdout
Manuel Jacob <me@manueljacob.de>
parents: 45083
diff changeset
153 # Python 2 uses the I/O streams provided by the C library.
45057
9694895749ad pycompat: remove pycompat.{stdin,stdout,stderr}
Manuel Jacob <me@manueljacob.de>
parents: 45048
diff changeset
154 stdin = sys.stdin
9694895749ad pycompat: remove pycompat.{stdin,stdout,stderr}
Manuel Jacob <me@manueljacob.de>
parents: 45048
diff changeset
155 stdout = sys.stdout
45148
a37f290a7124 windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents: 45103
diff changeset
156 stderr = sys.stderr
a37f290a7124 windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents: 45103
diff changeset
157 if pycompat.iswindows:
a37f290a7124 windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents: 45103
diff changeset
158 # Work around Windows bugs.
a37f290a7124 windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents: 45103
diff changeset
159 stdout = platform.winstdout(stdout)
a37f290a7124 windows: always work around EINVAL in case of broken pipe for stdout / stderr
Manuel Jacob <me@manueljacob.de>
parents: 45103
diff changeset
160 stderr = platform.winstdout(stderr)
45093
63196198dbf0 procutil: distribute code for stdout
Manuel Jacob <me@manueljacob.de>
parents: 45083
diff changeset
161 if isatty(stdout):
63196198dbf0 procutil: distribute code for stdout
Manuel Jacob <me@manueljacob.de>
parents: 45083
diff changeset
162 if pycompat.iswindows:
63196198dbf0 procutil: distribute code for stdout
Manuel Jacob <me@manueljacob.de>
parents: 45083
diff changeset
163 # The Windows C runtime library doesn't support line buffering.
63196198dbf0 procutil: distribute code for stdout
Manuel Jacob <me@manueljacob.de>
parents: 45083
diff changeset
164 stdout = make_line_buffered(stdout)
63196198dbf0 procutil: distribute code for stdout
Manuel Jacob <me@manueljacob.de>
parents: 45083
diff changeset
165 else:
63196198dbf0 procutil: distribute code for stdout
Manuel Jacob <me@manueljacob.de>
parents: 45083
diff changeset
166 # glibc determines buffering on first write to stdout - if we
63196198dbf0 procutil: distribute code for stdout
Manuel Jacob <me@manueljacob.de>
parents: 45083
diff changeset
167 # replace a TTY destined stdout with a pipe destined stdout (e.g.
63196198dbf0 procutil: distribute code for stdout
Manuel Jacob <me@manueljacob.de>
parents: 45083
diff changeset
168 # pager), we want line buffering.
63196198dbf0 procutil: distribute code for stdout
Manuel Jacob <me@manueljacob.de>
parents: 45083
diff changeset
169 stdout = os.fdopen(stdout.fileno(), 'wb', 1)
30908
3a4c0905f357 util: always force line buffered stdout when stdout is a tty (BC)
Simon Farnsworth <simonfar@fb.com>
parents: 30854
diff changeset
170
14926
4e7e63fc685a util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents: 14918
diff changeset
171
4e7e63fc685a util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents: 14918
diff changeset
172 findexe = platform.findexe
37118
49d6ba67c93f util: mark platform-specific gethgcmd() as private
Yuya Nishihara <yuya@tcha.org>
parents: 37102
diff changeset
173 _gethgcmd = platform.gethgcmd
14926
4e7e63fc685a util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents: 14918
diff changeset
174 getuser = platform.getuser
28027
14033c5dd261 util: enable getpid to be replaced
timeless <timeless@mozdev.org>
parents: 27785
diff changeset
175 getpid = os.getpid
14926
4e7e63fc685a util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents: 14918
diff changeset
176 hidewindow = platform.hidewindow
22245
234e4c24b980 platform: implement readpipe()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21914
diff changeset
177 readpipe = platform.readpipe
14926
4e7e63fc685a util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents: 14918
diff changeset
178 setbinary = platform.setbinary
4e7e63fc685a util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents: 14918
diff changeset
179 setsignalhandler = platform.setsignalhandler
4e7e63fc685a util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents: 14918
diff changeset
180 shellquote = platform.shellquote
36445
0cb09c322647 util: factor out shellsplit() function
Yuya Nishihara <yuya@tcha.org>
parents: 36395
diff changeset
181 shellsplit = platform.shellsplit
14926
4e7e63fc685a util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents: 14918
diff changeset
182 spawndetached = platform.spawndetached
4e7e63fc685a util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents: 14918
diff changeset
183 sshargs = platform.sshargs
4e7e63fc685a util: eliminate wildcard imports
Adrian Buehlmann <adrian@cadifra.com>
parents: 14918
diff changeset
184 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
185
32248
d74b0cff94a9 osutil: proxy through util (and platform) modules (API)
Yuya Nishihara <yuya@tcha.org>
parents: 32245
diff changeset
186 try:
d74b0cff94a9 osutil: proxy through util (and platform) modules (API)
Yuya Nishihara <yuya@tcha.org>
parents: 32245
diff changeset
187 setprocname = osutil.setprocname
d74b0cff94a9 osutil: proxy through util (and platform) modules (API)
Yuya Nishihara <yuya@tcha.org>
parents: 32245
diff changeset
188 except AttributeError:
d74b0cff94a9 osutil: proxy through util (and platform) modules (API)
Yuya Nishihara <yuya@tcha.org>
parents: 32245
diff changeset
189 pass
35464
8652ab4046e4 osutil: add a function to unblock signals
Jun Wu <quark@fb.com>
parents: 35166
diff changeset
190 try:
8652ab4046e4 osutil: add a function to unblock signals
Jun Wu <quark@fb.com>
parents: 35166
diff changeset
191 unblocksignal = osutil.unblocksignal
8652ab4046e4 osutil: add a function to unblock signals
Jun Wu <quark@fb.com>
parents: 35166
diff changeset
192 except AttributeError:
8652ab4046e4 osutil: add a function to unblock signals
Jun Wu <quark@fb.com>
parents: 35166
diff changeset
193 pass
32248
d74b0cff94a9 osutil: proxy through util (and platform) modules (API)
Yuya Nishihara <yuya@tcha.org>
parents: 32245
diff changeset
194
34646
238abf65a8ad codemod: use pycompat.isposix
Jun Wu <quark@fb.com>
parents: 34645
diff changeset
195 closefds = pycompat.isposix
10197
29e3c4a7699b subrepo: normalize svn output line-endings
Patrick Mezard <pmezard@gmail.com>
parents: 9996
diff changeset
196
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
197
37460
a6c6b7beb025 procutil: unify platform.explainexit()
Yuya Nishihara <yuya@tcha.org>
parents: 37459
diff changeset
198 def explainexit(code):
37463
bbd240f81ac5 procutil: make explainexit() simply return a message (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37462
diff changeset
199 """return a message describing a subprocess status
37460
a6c6b7beb025 procutil: unify platform.explainexit()
Yuya Nishihara <yuya@tcha.org>
parents: 37459
diff changeset
200 (codes from kill are negative - not os.system/wait encoding)"""
a6c6b7beb025 procutil: unify platform.explainexit()
Yuya Nishihara <yuya@tcha.org>
parents: 37459
diff changeset
201 if code >= 0:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
202 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
203 return _(b"killed by signal %d") % -code
37460
a6c6b7beb025 procutil: unify platform.explainexit()
Yuya Nishihara <yuya@tcha.org>
parents: 37459
diff changeset
204
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
205
37459
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37222
diff changeset
206 class _pfile(object):
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37222
diff changeset
207 """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: 37222
diff changeset
208
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37222
diff changeset
209 def __init__(self, proc, fp):
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37222
diff changeset
210 self._proc = proc
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37222
diff changeset
211 self._fp = fp
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37222
diff changeset
212
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37222
diff changeset
213 def close(self):
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37222
diff changeset
214 # 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: 37222
diff changeset
215 self._fp.close()
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37222
diff changeset
216 return self._proc.wait()
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37222
diff changeset
217
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37222
diff changeset
218 def __iter__(self):
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37222
diff changeset
219 return iter(self._fp)
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37222
diff changeset
220
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37222
diff changeset
221 def __getattr__(self, attr):
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37222
diff changeset
222 return getattr(self._fp, attr)
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37222
diff changeset
223
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37222
diff changeset
224 def __enter__(self):
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37222
diff changeset
225 return self
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37222
diff changeset
226
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37222
diff changeset
227 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: 37222
diff changeset
228 self.close()
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37222
diff changeset
229
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
230
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
231 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
232 if mode == b'rb':
37459
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37222
diff changeset
233 return _popenreader(cmd, bufsize)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
234 elif mode == b'wb':
37459
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37222
diff changeset
235 return _popenwriter(cmd, bufsize)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
236 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: 37222
diff changeset
237
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
238
37459
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37222
diff changeset
239 def _popenreader(cmd, bufsize):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
240 p = subprocess.Popen(
44926
8e8fd938ca07 cleanup: eliminate procutil.quotecommand()
Manuel Jacob <me@manueljacob.de>
parents: 44768
diff changeset
241 tonativestr(cmd),
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
242 shell=True,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
243 bufsize=bufsize,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
244 close_fds=closefds,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
245 stdout=subprocess.PIPE,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
246 )
37459
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37222
diff changeset
247 return _pfile(p, p.stdout)
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37222
diff changeset
248
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
249
37459
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37222
diff changeset
250 def _popenwriter(cmd, bufsize):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
251 p = subprocess.Popen(
44926
8e8fd938ca07 cleanup: eliminate procutil.quotecommand()
Manuel Jacob <me@manueljacob.de>
parents: 44768
diff changeset
252 tonativestr(cmd),
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
253 shell=True,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
254 bufsize=bufsize,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
255 close_fds=closefds,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
256 stdin=subprocess.PIPE,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
257 )
37459
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37222
diff changeset
258 return _pfile(p, p.stdin)
90c5ca718781 procutil: rewrite popen() as a subprocess.Popen wrapper (issue4746) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37222
diff changeset
259
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
260
37464
632b92899203 procutil: drop unused 'newlines' option from popen*() (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37463
diff changeset
261 def popen2(cmd, env=None):
9089
8ec39725d966 util: remove unused bufsize argument
Martin Geisler <mg@lazybytes.net>
parents: 9084
diff changeset
262 # 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
263 # 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
264 # poor performance on Mac OS X: http://bugs.python.org/issue4194
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
265 p = subprocess.Popen(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
266 tonativestr(cmd),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
267 shell=True,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
268 bufsize=-1,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
269 close_fds=closefds,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
270 stdin=subprocess.PIPE,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
271 stdout=subprocess.PIPE,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
272 env=tonativeenv(env),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
273 )
8280
0b02d98d44d0 util: always use subprocess
Martin Geisler <mg@lazybytes.net>
parents: 8257
diff changeset
274 return p.stdin, p.stdout
10197
29e3c4a7699b subrepo: normalize svn output line-endings
Patrick Mezard <pmezard@gmail.com>
parents: 9996
diff changeset
275
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
276
37464
632b92899203 procutil: drop unused 'newlines' option from popen*() (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37463
diff changeset
277 def popen3(cmd, env=None):
632b92899203 procutil: drop unused 'newlines' option from popen*() (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37463
diff changeset
278 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
279 return stdin, stdout, stderr
9baf4330d88f sshpeer: store subprocess so it cleans up correctly
Durham Goode <durham@fb.com>
parents: 18736
diff changeset
280
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
281
37464
632b92899203 procutil: drop unused 'newlines' option from popen*() (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37463
diff changeset
282 def popen4(cmd, env=None, bufsize=-1):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
283 p = subprocess.Popen(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
284 tonativestr(cmd),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
285 shell=True,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
286 bufsize=bufsize,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
287 close_fds=closefds,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
288 stdin=subprocess.PIPE,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
289 stdout=subprocess.PIPE,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
290 stderr=subprocess.PIPE,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
291 env=tonativeenv(env),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
292 )
18759
9baf4330d88f sshpeer: store subprocess so it cleans up correctly
Durham Goode <durham@fb.com>
parents: 18736
diff changeset
293 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
294
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
295
1293
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
296 def pipefilter(s, cmd):
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
297 '''filter string S through command CMD, returning its output'''
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
298 p = subprocess.Popen(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
299 tonativestr(cmd),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
300 shell=True,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
301 close_fds=closefds,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
302 stdin=subprocess.PIPE,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
303 stdout=subprocess.PIPE,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
304 )
8302
d2ad8c066676 util: simplify pipefilter and avoid subprocess race
Martin Geisler <mg@lazybytes.net>
parents: 8299
diff changeset
305 pout, perr = p.communicate(s)
d2ad8c066676 util: simplify pipefilter and avoid subprocess race
Martin Geisler <mg@lazybytes.net>
parents: 8299
diff changeset
306 return pout
419
28511fc21073 [PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff changeset
307
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
308
1293
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
309 def tempfilter(s, cmd):
45957
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45867
diff changeset
310 """filter string S through a pair of temporary files with CMD.
1293
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
311 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
312 with the strings INFILE and OUTFILE replaced by the real names of
45957
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45867
diff changeset
313 the temporary files generated."""
1293
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
314 inname, outname = None, None
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
315 try:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
316 infd, inname = pycompat.mkstemp(prefix=b'hg-filter-in-')
43554
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43551
diff changeset
317 fp = os.fdopen(infd, 'wb')
1293
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
318 fp.write(s)
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
319 fp.close()
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
320 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
321 os.close(outfd)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
322 cmd = cmd.replace(b'INFILE', inname)
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
323 cmd = cmd.replace(b'OUTFILE', outname)
37461
538353b80676 procutil: fix error message of tempfile filter
Yuya Nishihara <yuya@tcha.org>
parents: 37460
diff changeset
324 code = system(cmd)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
325 if pycompat.sysplatform == b'OpenVMS' and code & 1:
4720
72fb6f10fac1 OpenVMS patches
Jean-Francois PIERONNE <jf.pieronne@laposte.net>
parents: 4708
diff changeset
326 code = 0
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
327 if code:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
328 raise error.Abort(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
329 _(b"command '%s' failed: %s") % (cmd, explainexit(code))
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
330 )
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
331 with open(outname, b'rb') as fp:
37120
e7b517809ebc util: stop using readfile() in tempfilter()
Yuya Nishihara <yuya@tcha.org>
parents: 37119
diff changeset
332 return fp.read()
1293
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
333 finally:
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
334 try:
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
335 if inname:
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
336 os.unlink(inname)
14004
97ed99d1f419 eliminate various naked except clauses
Idan Kamara <idankk86@gmail.com>
parents: 13985
diff changeset
337 except OSError:
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
338 pass
1293
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
339 try:
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
340 if outname:
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
341 os.unlink(outname)
14004
97ed99d1f419 eliminate various naked except clauses
Idan Kamara <idankk86@gmail.com>
parents: 13985
diff changeset
342 except OSError:
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
343 pass
1293
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
344
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
345
37119
7ccc9b8aca4c util: mark filtertable as private constant
Yuya Nishihara <yuya@tcha.org>
parents: 37118
diff changeset
346 _filtertable = {
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
347 b'tempfile:': tempfilter,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
348 b'pipe:': pipefilter,
37119
7ccc9b8aca4c util: mark filtertable as private constant
Yuya Nishihara <yuya@tcha.org>
parents: 37118
diff changeset
349 }
1293
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
350
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
351
1293
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
352 def filter(s, cmd):
43807
be8552f25cab cleanup: fix docstring formatting
Matt Harbison <matt_harbison@yahoo.com>
parents: 43712
diff changeset
353 """filter a string through a command that transforms its input to its
be8552f25cab cleanup: fix docstring formatting
Matt Harbison <matt_harbison@yahoo.com>
parents: 43712
diff changeset
354 output"""
43106
d783f945a701 py3: finish porting iteritems() to pycompat and remove source transformer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43096
diff changeset
355 for name, fn in pycompat.iteritems(_filtertable):
1293
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
356 if cmd.startswith(name):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
357 return fn(s, cmd[len(name) :].lstrip())
1293
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
358 return pipefilter(s, cmd)
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
359
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
360
22632
db15bb2d6323 util: move _hgexecutable a few lines, closer to where it is used
Mads Kiilerich <madski@unity3d.com>
parents: 22245
diff changeset
361 _hgexecutable = None
db15bb2d6323 util: move _hgexecutable a few lines, closer to where it is used
Mads Kiilerich <madski@unity3d.com>
parents: 22245
diff changeset
362
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
363
5062
3d35c8cb5eb4 Simplify/correct finding the hg executable (fixes issue644)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4832
diff changeset
364 def hgexecutable():
3d35c8cb5eb4 Simplify/correct finding the hg executable (fixes issue644)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4832
diff changeset
365 """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
366
3d35c8cb5eb4 Simplify/correct finding the hg executable (fixes issue644)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4832
diff changeset
367 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
368 """
3d35c8cb5eb4 Simplify/correct finding the hg executable (fixes issue644)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4832
diff changeset
369 if _hgexecutable is None:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
370 hg = encoding.environ.get(b'HG')
43554
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43551
diff changeset
371 mainmod = sys.modules['__main__']
6500
a3175cd7dbec Tidy code, fix typo
Bryan O'Sullivan <bos@serpentine.com>
parents: 6499
diff changeset
372 if hg:
14229
85fd8402cbc4 rename util.set_hgexecutable to _sethgexecutable
Adrian Buehlmann <adrian@cadifra.com>
parents: 14228
diff changeset
373 _sethgexecutable(hg)
43712
664e24207728 procutil: move mainfrozen() to new resourceutil.py
Martin von Zweigbergk <martinvonz@google.com>
parents: 43701
diff changeset
374 elif resourceutil.mainfrozen():
43701
38387f9e4d22 py3: use native string for 'macosx_app'
Martin von Zweigbergk <martinvonz@google.com>
parents: 43700
diff changeset
375 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
376 # Env variable set by py2app
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
377 _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
378 else:
30672
10b17ed9b591 py3: replace sys.executable with pycompat.sysexecutable
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30647
diff changeset
379 _sethgexecutable(pycompat.sysexecutable)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
380 elif (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
381 not pycompat.iswindows
43700
47d983f0af65 py3: drop an unnecessary fsencode() before comparing with constant
Martin von Zweigbergk <martinvonz@google.com>
parents: 43699
diff changeset
382 and os.path.basename(getattr(mainmod, '__file__', '')) == 'hg'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
383 ):
31091
2912b06905dc py3: use pycompat.fsencode() to convert __file__ to bytes
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31008
diff changeset
384 _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
385 else:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
386 _sethgexecutable(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
387 findexe(b'hg') or os.path.basename(pycompat.sysargv[0])
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
388 )
5062
3d35c8cb5eb4 Simplify/correct finding the hg executable (fixes issue644)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4832
diff changeset
389 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
390
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
391
14229
85fd8402cbc4 rename util.set_hgexecutable to _sethgexecutable
Adrian Buehlmann <adrian@cadifra.com>
parents: 14228
diff changeset
392 def _sethgexecutable(path):
5062
3d35c8cb5eb4 Simplify/correct finding the hg executable (fixes issue644)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4832
diff changeset
393 """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
394 global _hgexecutable
5062
3d35c8cb5eb4 Simplify/correct finding the hg executable (fixes issue644)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4832
diff changeset
395 _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
396
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
397
36801
eca1051e6c22 util: add public isstdin/isstdout() functions
Yuya Nishihara <yuya@tcha.org>
parents: 36799
diff changeset
398 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
399 fileno = getattr(f, 'fileno', None)
36462
1ca4e86c7265 util: handle fileno() on Python 3 throwing io.UnsupportedOperation
Augie Fackler <augie@google.com>
parents: 36452
diff changeset
400 try:
36801
eca1051e6c22 util: add public isstdin/isstdout() functions
Yuya Nishihara <yuya@tcha.org>
parents: 36799
diff changeset
401 return fileno and fileno() == stdf.fileno()
36462
1ca4e86c7265 util: handle fileno() on Python 3 throwing io.UnsupportedOperation
Augie Fackler <augie@google.com>
parents: 36452
diff changeset
402 except io.UnsupportedOperation:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
403 return False # fileno() raised UnsupportedOperation
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
404
26450
1138e1d05207 util.system: compare fileno to see if it needs stdout redirection
Yuya Nishihara <yuya@tcha.org>
parents: 26392
diff changeset
405
36801
eca1051e6c22 util: add public isstdin/isstdout() functions
Yuya Nishihara <yuya@tcha.org>
parents: 36799
diff changeset
406 def isstdin(f):
eca1051e6c22 util: add public isstdin/isstdout() functions
Yuya Nishihara <yuya@tcha.org>
parents: 36799
diff changeset
407 return _testfileno(f, sys.__stdin__)
eca1051e6c22 util: add public isstdin/isstdout() functions
Yuya Nishihara <yuya@tcha.org>
parents: 36799
diff changeset
408
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
409
36801
eca1051e6c22 util: add public isstdin/isstdout() functions
Yuya Nishihara <yuya@tcha.org>
parents: 36799
diff changeset
410 def isstdout(f):
eca1051e6c22 util: add public isstdin/isstdout() functions
Yuya Nishihara <yuya@tcha.org>
parents: 36799
diff changeset
411 return _testfileno(f, sys.__stdout__)
eca1051e6c22 util: add public isstdin/isstdout() functions
Yuya Nishihara <yuya@tcha.org>
parents: 36799
diff changeset
412
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
413
37126
0216232f21ab procutil: move protectio/restoreio from commandserver
Yuya Nishihara <yuya@tcha.org>
parents: 37121
diff changeset
414 def protectstdio(uin, uout):
37222
7f78de1c93aa procutil: redirect ui.fout to stderr while stdio is protected
Yuya Nishihara <yuya@tcha.org>
parents: 37221
diff changeset
415 """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: 37221
diff changeset
416
7f78de1c93aa procutil: redirect ui.fout to stderr while stdio is protected
Yuya Nishihara <yuya@tcha.org>
parents: 37221
diff changeset
417 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: 37221
diff changeset
418 redirected to stderr so the output is still readable.
37126
0216232f21ab procutil: move protectio/restoreio from commandserver
Yuya Nishihara <yuya@tcha.org>
parents: 37121
diff changeset
419
0216232f21ab procutil: move protectio/restoreio from commandserver
Yuya Nishihara <yuya@tcha.org>
parents: 37121
diff changeset
420 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: 37121
diff changeset
421 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: 37121
diff changeset
422 "owned" in that print(), exec(), etc. never reach to them.
0216232f21ab procutil: move protectio/restoreio from commandserver
Yuya Nishihara <yuya@tcha.org>
parents: 37121
diff changeset
423 """
0216232f21ab procutil: move protectio/restoreio from commandserver
Yuya Nishihara <yuya@tcha.org>
parents: 37121
diff changeset
424 uout.flush()
37221
ac71cbad5da3 procutil: unroll uin/uout loop in protectstdio()
Yuya Nishihara <yuya@tcha.org>
parents: 37127
diff changeset
425 fin, fout = uin, uout
38799
e5724be689b3 procutil: compare fd number to see if stdio protection is needed (issue5992)
Yuya Nishihara <yuya@tcha.org>
parents: 38528
diff changeset
426 if _testfileno(uin, stdin):
37221
ac71cbad5da3 procutil: unroll uin/uout loop in protectstdio()
Yuya Nishihara <yuya@tcha.org>
parents: 37127
diff changeset
427 newfd = os.dup(uin.fileno())
37222
7f78de1c93aa procutil: redirect ui.fout to stderr while stdio is protected
Yuya Nishihara <yuya@tcha.org>
parents: 37221
diff changeset
428 nullfd = os.open(os.devnull, os.O_RDONLY)
37221
ac71cbad5da3 procutil: unroll uin/uout loop in protectstdio()
Yuya Nishihara <yuya@tcha.org>
parents: 37127
diff changeset
429 os.dup2(nullfd, uin.fileno())
37222
7f78de1c93aa procutil: redirect ui.fout to stderr while stdio is protected
Yuya Nishihara <yuya@tcha.org>
parents: 37221
diff changeset
430 os.close(nullfd)
43554
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43551
diff changeset
431 fin = os.fdopen(newfd, 'rb')
38799
e5724be689b3 procutil: compare fd number to see if stdio protection is needed (issue5992)
Yuya Nishihara <yuya@tcha.org>
parents: 38528
diff changeset
432 if _testfileno(uout, stdout):
37221
ac71cbad5da3 procutil: unroll uin/uout loop in protectstdio()
Yuya Nishihara <yuya@tcha.org>
parents: 37127
diff changeset
433 newfd = os.dup(uout.fileno())
37222
7f78de1c93aa procutil: redirect ui.fout to stderr while stdio is protected
Yuya Nishihara <yuya@tcha.org>
parents: 37221
diff changeset
434 os.dup2(stderr.fileno(), uout.fileno())
43554
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43551
diff changeset
435 fout = os.fdopen(newfd, 'wb')
37221
ac71cbad5da3 procutil: unroll uin/uout loop in protectstdio()
Yuya Nishihara <yuya@tcha.org>
parents: 37127
diff changeset
436 return fin, fout
37126
0216232f21ab procutil: move protectio/restoreio from commandserver
Yuya Nishihara <yuya@tcha.org>
parents: 37121
diff changeset
437
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
438
37126
0216232f21ab procutil: move protectio/restoreio from commandserver
Yuya Nishihara <yuya@tcha.org>
parents: 37121
diff changeset
439 def restorestdio(uin, uout, fin, fout):
0216232f21ab procutil: move protectio/restoreio from commandserver
Yuya Nishihara <yuya@tcha.org>
parents: 37121
diff changeset
440 """Restore (uin, uout) streams from possibly duplicated (fin, fout)"""
0216232f21ab procutil: move protectio/restoreio from commandserver
Yuya Nishihara <yuya@tcha.org>
parents: 37121
diff changeset
441 uout.flush()
0216232f21ab procutil: move protectio/restoreio from commandserver
Yuya Nishihara <yuya@tcha.org>
parents: 37121
diff changeset
442 for f, uif in [(fin, uin), (fout, uout)]:
0216232f21ab procutil: move protectio/restoreio from commandserver
Yuya Nishihara <yuya@tcha.org>
parents: 37121
diff changeset
443 if f is not uif:
0216232f21ab procutil: move protectio/restoreio from commandserver
Yuya Nishihara <yuya@tcha.org>
parents: 37121
diff changeset
444 os.dup2(f.fileno(), uif.fileno())
0216232f21ab procutil: move protectio/restoreio from commandserver
Yuya Nishihara <yuya@tcha.org>
parents: 37121
diff changeset
445 f.close()
0216232f21ab procutil: move protectio/restoreio from commandserver
Yuya Nishihara <yuya@tcha.org>
parents: 37121
diff changeset
446
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
447
30736
d9e5b0aeeb90 util: extract the logic calculating environment variables
Jun Wu <quark@fb.com>
parents: 30672
diff changeset
448 def shellenviron(environ=None):
d9e5b0aeeb90 util: extract the logic calculating environment variables
Jun Wu <quark@fb.com>
parents: 30672
diff changeset
449 """return environ with optional override, useful for shelling out"""
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
450
30736
d9e5b0aeeb90 util: extract the logic calculating environment variables
Jun Wu <quark@fb.com>
parents: 30672
diff changeset
451 def py2shell(val):
43807
be8552f25cab cleanup: fix docstring formatting
Matt Harbison <matt_harbison@yahoo.com>
parents: 43712
diff changeset
452 """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: 30672
diff changeset
453 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
454 return b'0'
30736
d9e5b0aeeb90 util: extract the logic calculating environment variables
Jun Wu <quark@fb.com>
parents: 30672
diff changeset
455 if val is True:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
456 return b'1'
36448
d26b0bedfaa4 util: use pycompat.bytestr() instead of str()
Augie Fackler <augie@google.com>
parents: 36445
diff changeset
457 return pycompat.bytestr(val)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
458
30736
d9e5b0aeeb90 util: extract the logic calculating environment variables
Jun Wu <quark@fb.com>
parents: 30672
diff changeset
459 env = dict(encoding.environ)
d9e5b0aeeb90 util: extract the logic calculating environment variables
Jun Wu <quark@fb.com>
parents: 30672
diff changeset
460 if environ:
43106
d783f945a701 py3: finish porting iteritems() to pycompat and remove source transformer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43096
diff changeset
461 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
462 env[b'HG'] = hgexecutable()
30736
d9e5b0aeeb90 util: extract the logic calculating environment variables
Jun Wu <quark@fb.com>
parents: 30672
diff changeset
463 return env
d9e5b0aeeb90 util: extract the logic calculating environment variables
Jun Wu <quark@fb.com>
parents: 30672
diff changeset
464
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
465
38495
72286f9e324f procutil: add a shim for translating shell commands to native commands
Matt Harbison <matt_harbison@yahoo.com>
parents: 38459
diff changeset
466 if pycompat.iswindows:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
467
38495
72286f9e324f procutil: add a shim for translating shell commands to native commands
Matt Harbison <matt_harbison@yahoo.com>
parents: 38459
diff changeset
468 def shelltonative(cmd, env):
43526
54f4d094bab1 procutil: suppress pytype warnings around windows-only attributes
Augie Fackler <augie@google.com>
parents: 43165
diff changeset
469 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
470 cmd, shellenviron(env)
54f4d094bab1 procutil: suppress pytype warnings around windows-only attributes
Augie Fackler <augie@google.com>
parents: 43165
diff changeset
471 )
39678
50f46b771921 py3: partially fix pager spawning on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 38528
diff changeset
472
50f46b771921 py3: partially fix pager spawning on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 38528
diff changeset
473 tonativestr = encoding.strfromlocal
38495
72286f9e324f procutil: add a shim for translating shell commands to native commands
Matt Harbison <matt_harbison@yahoo.com>
parents: 38459
diff changeset
474 else:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
475
38495
72286f9e324f procutil: add a shim for translating shell commands to native commands
Matt Harbison <matt_harbison@yahoo.com>
parents: 38459
diff changeset
476 def shelltonative(cmd, env):
72286f9e324f procutil: add a shim for translating shell commands to native commands
Matt Harbison <matt_harbison@yahoo.com>
parents: 38459
diff changeset
477 return cmd
72286f9e324f procutil: add a shim for translating shell commands to native commands
Matt Harbison <matt_harbison@yahoo.com>
parents: 38459
diff changeset
478
39678
50f46b771921 py3: partially fix pager spawning on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 38528
diff changeset
479 tonativestr = pycompat.identity
50f46b771921 py3: partially fix pager spawning on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 38528
diff changeset
480
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
481
39678
50f46b771921 py3: partially fix pager spawning on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 38528
diff changeset
482 def tonativeenv(env):
45957
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45867
diff changeset
483 """convert the environment from bytes to strings suitable for Popen(), etc."""
39678
50f46b771921 py3: partially fix pager spawning on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 38528
diff changeset
484 return pycompat.rapply(tonativestr, env)
50f46b771921 py3: partially fix pager spawning on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 38528
diff changeset
485
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
486
31125
3f8f53190d6a chg: deduplicate error handling of ui.system()
Yuya Nishihara <yuya@tcha.org>
parents: 31091
diff changeset
487 def system(cmd, environ=None, cwd=None, out=None):
45957
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45867
diff changeset
488 """enhanced shell command execution.
1882
c0320567931f merge util.esystem and util.system.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1880
diff changeset
489 run with environment maybe modified, maybe in different dir.
508
42a660abaf75 [PATCH] Harden os.system
mpm@selenic.com
parents: 464
diff changeset
490
11469
c37f35d7f2f5 http: deliver hook output to client
Maxim Khitrov <mkhitrov@gmail.com>
parents: 11297
diff changeset
491 if out is specified, it is assumed to be a file-like object that has a
45957
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45867
diff changeset
492 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
493 try:
30482
39d13b8c101d py3: bulk replace sys.stdin/out/err by util's
Yuya Nishihara <yuya@tcha.org>
parents: 30481
diff changeset
494 stdout.flush()
13439
d724a69309e0 util: flush stdout before calling external processes
Mads Kiilerich <mads@kiilerich.com>
parents: 13400
diff changeset
495 except Exception:
d724a69309e0 util: flush stdout before calling external processes
Mads Kiilerich <mads@kiilerich.com>
parents: 13400
diff changeset
496 pass
32904
19b0fd4b5570 plan9: drop py26 hacks
Matt Harbison <matt_harbison@yahoo.com>
parents: 32835
diff changeset
497 env = shellenviron(environ)
36801
eca1051e6c22 util: add public isstdin/isstdout() functions
Yuya Nishihara <yuya@tcha.org>
parents: 36799
diff changeset
498 if out is None or isstdout(out):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
499 rc = subprocess.call(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
500 tonativestr(cmd),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
501 shell=True,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
502 close_fds=closefds,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
503 env=tonativeenv(env),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
504 cwd=pycompat.rapply(tonativestr, cwd),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
505 )
11469
c37f35d7f2f5 http: deliver hook output to client
Maxim Khitrov <mkhitrov@gmail.com>
parents: 11297
diff changeset
506 else:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
507 proc = subprocess.Popen(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
508 tonativestr(cmd),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
509 shell=True,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
510 close_fds=closefds,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
511 env=tonativeenv(env),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
512 cwd=pycompat.rapply(tonativestr, cwd),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
513 stdout=subprocess.PIPE,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
514 stderr=subprocess.STDOUT,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
515 )
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
516 for line in iter(proc.stdout.readline, b''):
32904
19b0fd4b5570 plan9: drop py26 hacks
Matt Harbison <matt_harbison@yahoo.com>
parents: 32835
diff changeset
517 out.write(line)
19b0fd4b5570 plan9: drop py26 hacks
Matt Harbison <matt_harbison@yahoo.com>
parents: 32835
diff changeset
518 proc.wait()
19b0fd4b5570 plan9: drop py26 hacks
Matt Harbison <matt_harbison@yahoo.com>
parents: 32835
diff changeset
519 rc = proc.returncode
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
520 if pycompat.sysplatform == b'OpenVMS' and rc & 1:
32904
19b0fd4b5570 plan9: drop py26 hacks
Matt Harbison <matt_harbison@yahoo.com>
parents: 32835
diff changeset
521 rc = 0
9517
4368f582c806 util.system: Use subprocess instead of os.system
Mads Kiilerich <mads@kiilerich.com>
parents: 9508
diff changeset
522 return rc
1880
05c7d75be925 fix broken environment save/restore when a hook runs.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1877
diff changeset
523
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
524
43918
a89381e04c58 procutil: try and avoid angering CoreFoundation on macOS
Augie Fackler <augie@google.com>
parents: 43873
diff changeset
525 _is_gui = None
a89381e04c58 procutil: try and avoid angering CoreFoundation on macOS
Augie Fackler <augie@google.com>
parents: 43873
diff changeset
526
a89381e04c58 procutil: try and avoid angering CoreFoundation on macOS
Augie Fackler <augie@google.com>
parents: 43873
diff changeset
527
a89381e04c58 procutil: try and avoid angering CoreFoundation on macOS
Augie Fackler <augie@google.com>
parents: 43873
diff changeset
528 def _gui():
6007
090b1a665901 filemerge: add config item for GUI tools
Matt Mackall <mpm@selenic.com>
parents: 6006
diff changeset
529 '''Are we running in a GUI?'''
34647
dacfcdd8b94e codemod: use pycompat.isdarwin
Jun Wu <quark@fb.com>
parents: 34646
diff changeset
530 if pycompat.isdarwin:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
531 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
532 # 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
533 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
534 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
535 # 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
536 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
537 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
538 # 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
539 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
540 else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
541 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
542
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
543
43918
a89381e04c58 procutil: try and avoid angering CoreFoundation on macOS
Augie Fackler <augie@google.com>
parents: 43873
diff changeset
544 def gui():
a89381e04c58 procutil: try and avoid angering CoreFoundation on macOS
Augie Fackler <augie@google.com>
parents: 43873
diff changeset
545 global _is_gui
a89381e04c58 procutil: try and avoid angering CoreFoundation on macOS
Augie Fackler <augie@google.com>
parents: 43873
diff changeset
546 if _is_gui is None:
a89381e04c58 procutil: try and avoid angering CoreFoundation on macOS
Augie Fackler <augie@google.com>
parents: 43873
diff changeset
547 _is_gui = _gui()
a89381e04c58 procutil: try and avoid angering CoreFoundation on macOS
Augie Fackler <augie@google.com>
parents: 43873
diff changeset
548 return _is_gui
a89381e04c58 procutil: try and avoid angering CoreFoundation on macOS
Augie Fackler <augie@google.com>
parents: 43873
diff changeset
549
a89381e04c58 procutil: try and avoid angering CoreFoundation on macOS
Augie Fackler <augie@google.com>
parents: 43873
diff changeset
550
10239
8e4be44a676f Find right hg command for detached process
Patrick Mezard <pmezard@gmail.com>
parents: 10199
diff changeset
551 def hgcmd():
8e4be44a676f Find right hg command for detached process
Patrick Mezard <pmezard@gmail.com>
parents: 10199
diff changeset
552 """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
553
8e4be44a676f Find right hg command for detached process
Patrick Mezard <pmezard@gmail.com>
parents: 10199
diff changeset
554 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
555 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
556 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
557 """
43712
664e24207728 procutil: move mainfrozen() to new resourceutil.py
Martin von Zweigbergk <martinvonz@google.com>
parents: 43701
diff changeset
558 if resourceutil.mainfrozen():
43701
38387f9e4d22 py3: use native string for 'macosx_app'
Martin von Zweigbergk <martinvonz@google.com>
parents: 43700
diff changeset
559 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
560 # Env variable set by py2app
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
561 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
562 else:
30672
10b17ed9b591 py3: replace sys.executable with pycompat.sysexecutable
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30647
diff changeset
563 return [pycompat.sysexecutable]
37118
49d6ba67c93f util: mark platform-specific gethgcmd() as private
Yuya Nishihara <yuya@tcha.org>
parents: 37102
diff changeset
564 return _gethgcmd()
10344
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
565
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
566
10344
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
567 def rundetached(args, condfn):
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
568 """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
569
10344
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
570 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
571 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
572 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
573 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
574 True, return -1.
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
575 """
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
576 # 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
577 # 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
578 # 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
579 # 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
580 # 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
581 # 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
582 # us our child process terminated.
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
583 terminated = set()
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
584
10344
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
585 def handler(signum, frame):
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
586 terminated.add(os.wait())
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
587
10344
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
588 prevhandler = None
14968
b7dbe957585c util: use safehasattr or getattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents: 14942
diff changeset
589 SIGCHLD = getattr(signal, 'SIGCHLD', None)
b7dbe957585c util: use safehasattr or getattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents: 14942
diff changeset
590 if SIGCHLD is not None:
b7dbe957585c util: use safehasattr or getattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents: 14942
diff changeset
591 prevhandler = signal.signal(SIGCHLD, handler)
10344
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
592 try:
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
593 pid = spawndetached(args)
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
594 while not condfn():
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
595 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
596 return -1
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
597 time.sleep(0.1)
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
598 return pid
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
599 finally:
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
600 if prevhandler is not None:
9501cde4c034 util: make spawndetached() handle subprocess early terminations
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
601 signal.signal(signal.SIGCHLD, prevhandler)
38528
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38527
diff changeset
602
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
603
38528
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38527
diff changeset
604 @contextlib.contextmanager
41079
8ecb17b7f432 procutil: correct spelling of uninterruptable -> uninterruptible
Kyle Lippincott <spectral@google.com>
parents: 40751
diff changeset
605 def uninterruptible(warn):
38528
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38527
diff changeset
606 """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: 38527
diff changeset
607
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38527
diff changeset
608 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: 38527
diff changeset
609
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38527
diff changeset
610 Args:
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38527
diff changeset
611 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: 38527
diff changeset
612 previous signal handling should be restored.
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38527
diff changeset
613 """
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38527
diff changeset
614
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38527
diff changeset
615 oldsiginthandler = [signal.getsignal(signal.SIGINT)]
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38527
diff changeset
616 shouldbail = []
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38527
diff changeset
617
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38527
diff changeset
618 def disabledsiginthandler(*args):
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38527
diff changeset
619 if warn():
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38527
diff changeset
620 signal.signal(signal.SIGINT, oldsiginthandler[0])
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38527
diff changeset
621 del oldsiginthandler[0]
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38527
diff changeset
622 shouldbail.append(True)
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38527
diff changeset
623
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38527
diff changeset
624 try:
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38527
diff changeset
625 try:
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38527
diff changeset
626 signal.signal(signal.SIGINT, disabledsiginthandler)
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38527
diff changeset
627 except ValueError:
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38527
diff changeset
628 # wrong thread, oh well, we tried
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38527
diff changeset
629 del oldsiginthandler[0]
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38527
diff changeset
630 yield
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38527
diff changeset
631 finally:
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38527
diff changeset
632 if oldsiginthandler:
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38527
diff changeset
633 signal.signal(signal.SIGINT, oldsiginthandler[0])
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38527
diff changeset
634 if shouldbail:
313a940d49a3 ui: add an uninterruptable context manager that can block SIGINT
Augie Fackler <augie@google.com>
parents: 38527
diff changeset
635 raise KeyboardInterrupt
40547
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39845
diff changeset
636
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
637
40547
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39845
diff changeset
638 if pycompat.iswindows:
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39845
diff changeset
639 # no fork on Windows, but we can create a detached process
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39845
diff changeset
640 # https://msdn.microsoft.com/en-us/library/windows/desktop/ms684863.aspx
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39845
diff changeset
641 # No stdlib constant exists for this value
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39845
diff changeset
642 DETACHED_PROCESS = 0x00000008
40586
1d3bed7d2923 procutil: import concerns about creationflags on Windows from D1701
Boris Feld <boris.feld@octobus.net>
parents: 40548
diff changeset
643 # 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: 40548
diff changeset
644 # Using subprocess.CREATE_NEW_CONSOLE might helps.
1d3bed7d2923 procutil: import concerns about creationflags on Windows from D1701
Boris Feld <boris.feld@octobus.net>
parents: 40548
diff changeset
645 # See https://phab.mercurial-scm.org/D1701 for discussion
43526
54f4d094bab1 procutil: suppress pytype warnings around windows-only attributes
Augie Fackler <augie@google.com>
parents: 43165
diff changeset
646 _creationflags = (
54f4d094bab1 procutil: suppress pytype warnings around windows-only attributes
Augie Fackler <augie@google.com>
parents: 43165
diff changeset
647 DETACHED_PROCESS
54f4d094bab1 procutil: suppress pytype warnings around windows-only attributes
Augie Fackler <augie@google.com>
parents: 43165
diff changeset
648 | 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
649 )
40547
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39845
diff changeset
650
42511
ca1014ad3de4 procutil: allow callers of runbgcommand to assume the process starts
Augie Fackler <augie@google.com>
parents: 41837
diff changeset
651 def runbgcommand(
43456
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
652 script,
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
653 env,
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
654 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
655 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
656 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
657 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
658 record_wait=None,
45809
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
659 stdin_bytes=None,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
660 ):
40547
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39845
diff changeset
661 '''Spawn a command without waiting for it to finish.'''
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39845
diff changeset
662 # 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: 39845
diff changeset
663 # need to because the detached process has no console connection.
45809
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
664
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
665 try:
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
666 stdin = None
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
667 if stdin_bytes is not None:
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
668 stdin = pycompat.unnamedtempfile()
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
669 stdin.write(stdin_bytes)
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
670 stdin.flush()
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
671 stdin.seek(0)
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
672
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
673 p = subprocess.Popen(
46034
2cf61e66c6d0 merge with stable
Augie Fackler <augie@google.com>
parents: 45957 45772
diff changeset
674 pycompat.rapply(tonativestr, script),
45809
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
675 shell=shell,
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
676 env=tonativeenv(env),
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
677 close_fds=True,
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
678 creationflags=_creationflags,
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
679 stdin=stdin,
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
680 stdout=stdout,
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
681 stderr=stderr,
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
682 )
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
683 if record_wait is not None:
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
684 record_wait(p.wait)
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
685 finally:
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
686 if stdin is not None:
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
687 stdin.close()
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
688
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
689
40547
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39845
diff changeset
690 else:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
691
42511
ca1014ad3de4 procutil: allow callers of runbgcommand to assume the process starts
Augie Fackler <augie@google.com>
parents: 41837
diff changeset
692 def runbgcommand(
43456
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
693 cmd,
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
694 env,
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
695 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
696 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
697 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
698 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
699 record_wait=None,
45809
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
700 stdin_bytes=None,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
701 ):
45957
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45867
diff changeset
702 """Spawn a command without waiting for it to finish.
43456
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
703
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
704
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
705 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
706 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
707 `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
708 useful for developers that need to make sure the spawned process
45957
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45867
diff changeset
709 finished before a certain point. (eg: writing test)"""
43918
a89381e04c58 procutil: try and avoid angering CoreFoundation on macOS
Augie Fackler <augie@google.com>
parents: 43873
diff changeset
710 if pycompat.isdarwin:
a89381e04c58 procutil: try and avoid angering CoreFoundation on macOS
Augie Fackler <augie@google.com>
parents: 43873
diff changeset
711 # avoid crash in CoreFoundation in case another thread
a89381e04c58 procutil: try and avoid angering CoreFoundation on macOS
Augie Fackler <augie@google.com>
parents: 43873
diff changeset
712 # calls gui() while we're calling fork().
a89381e04c58 procutil: try and avoid angering CoreFoundation on macOS
Augie Fackler <augie@google.com>
parents: 43873
diff changeset
713 gui()
a89381e04c58 procutil: try and avoid angering CoreFoundation on macOS
Augie Fackler <augie@google.com>
parents: 43873
diff changeset
714
40547
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39845
diff changeset
715 # double-fork to completely detach from the parent process
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39845
diff changeset
716 # based on http://code.activestate.com/recipes/278731
43456
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
717 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
718 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
719 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
720 if not ensurestart:
44764
ed684a82e29b procutil: always waiting on child processes to prevent zombies with 'hg serve'
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 43918
diff changeset
721 # 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: 43918
diff changeset
722 # 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: 43918
diff changeset
723 # 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: 43918
diff changeset
724 # 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: 43918
diff changeset
725 # 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: 43918
diff changeset
726 def _do_wait():
ed684a82e29b procutil: always waiting on child processes to prevent zombies with 'hg serve'
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 43918
diff changeset
727 os.waitpid(pid, 0)
44768
79f6f856c53f formatting: add missing newline
Raphaël Gomès <rgomes@octobus.net>
parents: 44764
diff changeset
728
44822
95c672c07116 procutil: make recent fix for zombies compatible with py2
Martin von Zweigbergk <martinvonz@google.com>
parents: 44797
diff changeset
729 t = threading.Thread(target=_do_wait)
95c672c07116 procutil: make recent fix for zombies compatible with py2
Martin von Zweigbergk <martinvonz@google.com>
parents: 44797
diff changeset
730 t.daemon = True
95c672c07116 procutil: make recent fix for zombies compatible with py2
Martin von Zweigbergk <martinvonz@google.com>
parents: 44797
diff changeset
731 t.start()
43456
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
732 return
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
733 # 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
734 (_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
735 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
736 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
737 else:
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
738 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
739 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
740 # 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
741 # 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
742 # value.
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
743 #
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
744 # (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
745 # 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
746 # 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
747 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
748 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
749 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
750 returncode,
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
751 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
752 % (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
753 )
42511
ca1014ad3de4 procutil: allow callers of runbgcommand to assume the process starts
Augie Fackler <augie@google.com>
parents: 41837
diff changeset
754 return
40547
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39845
diff changeset
755
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39845
diff changeset
756 returncode = 255
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39845
diff changeset
757 try:
43456
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
758 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
759 # 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
760 os.setsid()
45809
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
761 # connect stdin to devnull to make sure the subprocess can't
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
762 # muck up that stream for mercurial.
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
763 if stdin_bytes is None:
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
764 stdin = open(os.devnull, b'r')
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
765 else:
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
766 stdin = pycompat.unnamedtempfile()
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
767 stdin.write(stdin_bytes)
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
768 stdin.flush()
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
769 stdin.seek(0)
40547
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39845
diff changeset
770
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39845
diff changeset
771 if stdout is None:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
772 stdout = open(os.devnull, b'w')
40547
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39845
diff changeset
773 if stderr is None:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
774 stderr = open(os.devnull, b'w')
40547
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39845
diff changeset
775
43456
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
776 p = subprocess.Popen(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
777 cmd,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
778 shell=shell,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
779 env=env,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
780 close_fds=True,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
781 stdin=stdin,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
782 stdout=stdout,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
783 stderr=stderr,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
784 )
43456
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
785 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
786 record_wait(p.wait)
40547
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39845
diff changeset
787 returncode = 0
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39845
diff changeset
788 except EnvironmentError as ex:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
789 returncode = ex.errno & 0xFF
40547
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39845
diff changeset
790 if returncode == 0:
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39845
diff changeset
791 # This shouldn't happen, but just in case make sure the
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39845
diff changeset
792 # return code is never 0 here.
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39845
diff changeset
793 returncode = 255
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39845
diff changeset
794 except Exception:
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39845
diff changeset
795 returncode = 255
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39845
diff changeset
796 finally:
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39845
diff changeset
797 # mission accomplished, this child needs to exit and not
3fbfbc8c9f82 remotefilelog: transplant runbgcommand to procutil
Augie Fackler <augie@google.com>
parents: 39845
diff changeset
798 # continue the hg process here.
45809
37c65704869d procutil: allow to specify arbitrary stdin bytes to runbgcommand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45148
diff changeset
799 stdin.close()
43456
15a6c6783060 procutil: add a option to not fully detach background process
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43165
diff changeset
800 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
801 os._exit(returncode)