blob: ca5858a9b68e9a2e5643b84d015fd22935594fdc [file] [log] [blame]
Owen Lin9d19b272013-11-28 12:13:24 +08001#!/usr/bin/python
2# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6import logging
7import pipes
8import subprocess
9
10
11def wait_and_check_returncode(*popens):
12 '''Wait for all the Popens and check the return code is 0.
13
14 If the return code is not 0, it raises an RuntimeError.
15 '''
16 for p in popens:
17 if p.wait() != 0:
18 raise RuntimeError(
19 'Command failed(%d, %d): %s' %
20 (p.pid, p.returncode, p.command))
21
22
23def execute(args, stdin=None, stdout=None):
24 '''Executes a child command and wait for it.
25
26 Returns the output from standard output if 'stdout' is subprocess.PIPE.
27 Raises RuntimeException if the return code of the child command is not 0.
28
29 @param args: the command to be executed
30 @param stdin: the executed program's standard input
31 @param stdout: the executed program's stdandrd output
32 '''
33 ps = popen(args, stdin=stdin, stdout=stdout)
34 out = ps.communicate()[0] if stdout == subprocess.PIPE else None
35 wait_and_check_returncode(ps)
36 return out
37
38
39def popen(*args, **kargs):
40 '''Returns a Popen object just as subprocess.Popen does but with the
41 executed command stored in Popen.command.
42 '''
43 ps = subprocess.Popen(*args, **kargs)
44 the_args = args[0] if len(args) > 0 else kargs['args']
45 ps.command = ' '.join(pipes.quote(x) for x in the_args)
46 logging.info('Running(%d): %s', ps.pid, ps.command)
47 return ps