Commit 0963d545 authored by René Nussbaumer's avatar René Nussbaumer
Browse files

Make it possible to invoke RunCmd in interactive mode



This is needed so we can run external scripts asking for password and such
to run interactive. Downside is that we can't get the output of the program
but we can still use the exit code.
Signed-off-by: default avatarRené Nussbaumer <rn@google.com>
Reviewed-by: default avatarIustin Pop <iustin@google.com>
parent e8d61457
......@@ -158,7 +158,8 @@ def _BuildCmdEnvironment(env, reset):
return cmd_env
def RunCmd(cmd, env=None, output=None, cwd="/", reset_env=False):
def RunCmd(cmd, env=None, output=None, cwd="/", reset_env=False,
interactive=False):
"""Execute a (shell) command.
The command should not read from its standard input, as it will be
......@@ -177,6 +178,9 @@ def RunCmd(cmd, env=None, output=None, cwd="/", reset_env=False):
directory for the command; the default will be /
@type reset_env: boolean
@param reset_env: whether to reset or keep the default os environment
@type interactive: boolean
@param interactive: weather we pipe stdin, stdout and stderr
(default behaviour) or run the command interactive
@rtype: L{RunResult}
@return: RunResult instance
@raise errors.ProgrammerError: if we call this when forks are disabled
......@@ -185,6 +189,10 @@ def RunCmd(cmd, env=None, output=None, cwd="/", reset_env=False):
if no_fork:
raise errors.ProgrammerError("utils.RunCmd() called with fork() disabled")
if output and interactive:
raise errors.ProgrammerError("Parameters 'output' and 'interactive' can"
" not be provided at the same time")
if isinstance(cmd, basestring):
strcmd = cmd
shell = True
......@@ -202,7 +210,7 @@ def RunCmd(cmd, env=None, output=None, cwd="/", reset_env=False):
try:
if output is None:
out, err, status = _RunCmdPipe(cmd, cmd_env, shell, cwd)
out, err, status = _RunCmdPipe(cmd, cmd_env, shell, cwd, interactive)
else:
status = _RunCmdFile(cmd, cmd_env, shell, output, cwd)
out = err = ""
......@@ -418,7 +426,7 @@ def _StartDaemonChild(errpipe_read, errpipe_write,
os._exit(1) # pylint: disable-msg=W0212
def _RunCmdPipe(cmd, env, via_shell, cwd):
def _RunCmdPipe(cmd, env, via_shell, cwd, interactive):
"""Run a command and return its output.
@type cmd: string or list
......@@ -429,23 +437,34 @@ def _RunCmdPipe(cmd, env, via_shell, cwd):
@param via_shell: if we should run via the shell
@type cwd: string
@param cwd: the working directory for the program
@type interactive: boolean
@param interactive: Run command interactive (without piping)
@rtype: tuple
@return: (out, err, status)
"""
poller = select.poll()
stderr = subprocess.PIPE
stdout = subprocess.PIPE
stdin = subprocess.PIPE
if interactive:
stderr = stdout = stdin = None
child = subprocess.Popen(cmd, shell=via_shell,
stderr=subprocess.PIPE,
stdout=subprocess.PIPE,
stdin=subprocess.PIPE,
stderr=stderr,
stdout=stdout,
stdin=stdin,
close_fds=True, env=env,
cwd=cwd)
out = StringIO()
err = StringIO()
if not interactive:
child.stdin.close()
poller.register(child.stdout, select.POLLIN)
poller.register(child.stderr, select.POLLIN)
out = StringIO()
err = StringIO()
fdmap = {
child.stdout.fileno(): (out, child.stdout),
child.stderr.fileno(): (err, child.stderr),
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment