Mercurial > hg
changeset 45786:37c65704869d
procutil: allow to specify arbitrary stdin bytes to runbgcommand
For automatic clonebundles generation I need to pass arbitrary large amount of
data to the process (eg: common nodes, target nodes).
I am updating the `runbgcommand` to allow for this. Previously not stdin input
was possible, now, one can provide raw bytes and they will be feed to the
command through an unnamed temporary files.
Differential Revision: https://phab.mercurial-scm.org/D9212
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Wed, 14 Oct 2020 17:52:18 +0200 |
parents | 80f32ec8653a |
children | 225e513c444e |
files | mercurial/utils/procutil.py |
diffstat | 1 files changed, 36 insertions(+), 14 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/utils/procutil.py Wed Oct 14 17:46:28 2020 +0200 +++ b/mercurial/utils/procutil.py Wed Oct 14 17:52:18 2020 +0200 @@ -635,21 +635,35 @@ stderr=None, ensurestart=True, record_wait=None, + stdin_bytes=None, ): '''Spawn a command without waiting for it to finish.''' # we can't use close_fds *and* redirect stdin. I'm not sure that we # need to because the detached process has no console connection. - p = subprocess.Popen( - tonativestr(script), - shell=shell, - env=tonativeenv(env), - close_fds=True, - creationflags=_creationflags, - stdout=stdout, - stderr=stderr, - ) - if record_wait is not None: - record_wait(p.wait) + + try: + stdin = None + if stdin_bytes is not None: + stdin = pycompat.unnamedtempfile() + stdin.write(stdin_bytes) + stdin.flush() + stdin.seek(0) + + p = subprocess.Popen( + tonativestr(script), + shell=shell, + env=tonativeenv(env), + close_fds=True, + creationflags=_creationflags, + stdin=stdin, + stdout=stdout, + stderr=stderr, + ) + if record_wait is not None: + record_wait(p.wait) + finally: + if stdin is not None: + stdin.close() else: @@ -662,6 +676,7 @@ stderr=None, ensurestart=True, record_wait=None, + stdin_bytes=None, ): '''Spawn a command without waiting for it to finish. @@ -722,15 +737,21 @@ if record_wait is None: # Start a new session os.setsid() + # connect stdin to devnull to make sure the subprocess can't + # muck up that stream for mercurial. + if stdin_bytes is None: + stdin = open(os.devnull, b'r') + else: + stdin = pycompat.unnamedtempfile() + stdin.write(stdin_bytes) + stdin.flush() + stdin.seek(0) - stdin = open(os.devnull, b'r') if stdout is None: stdout = open(os.devnull, b'w') if stderr is None: stderr = open(os.devnull, b'w') - # connect stdin to devnull to make sure the subprocess can't - # muck up that stream for mercurial. p = subprocess.Popen( cmd, shell=shell, @@ -754,5 +775,6 @@ finally: # mission accomplished, this child needs to exit and not # continue the hg process here. + stdin.close() if record_wait is None: os._exit(returncode)