(cmd, stdinput=None, env=None, cwd=None, sudo=False,
                sudo_password=None, background=False, stream_output=False,
                timeout=0, waitfor=0)
Executes cmd using suprocess.

  Args:
    cmd: An array of strings as the command to run
    stdinput: An optional string as stdin
    env: An optional dictionary as the environment
    cwd: An optional string as the current working directory
    sudo: An optional boolean on whether to do the command via sudo
    sudo_password: An optional string of the password to use for sudo
    background: Launch command in background mode
    stream_output: An optional boolean on whether to send output to the screen
    timeout: An optional int or float; if >0, Exec() will stop waiting for
      output after timeout seconds and kill the process it started. Return code
      might be undefined, or -SIGTERM, use waitfor to make sure to obtain it.
      values <1 will be crudely rounded off because of select() sleep time.
    waitfor: An optional int or float, if >0, Exec() will wait waitfor seconds
      before asking for the process exit status one more time.
  Returns:
    Tuple: two strings and an integer: (stdout, stderr, returncode);
    stdout/stderr may also be None. If the process is set to launch in
    background mode, an instance of <subprocess.Popen object> is
    returned, in order to be able to read from its pipes *and* use poll() to
    check when it is finished.
  Raises:
    GmacpyutilException: If both stdinput and sudo_password are specified
    GmacpyutilException: If both sudo and background are specified
    GmacpyutilException: If both timeout and background, stream_output, sudo, or
      sudo_password, or stdinput are specified
    GmacpyutilException: If timeout is less than 0
    GmacpyutilException: If subprocess raises an OSError
Executes cmd using suprocess.
Executes cmd using suprocess .
def _RunProcess(cmd, stdinput=None, env=None, cwd=None, sudo=False,
                sudo_password=None, background=False, stream_output=False,
                timeout=0, waitfor=0):
  """Executes cmd using suprocess.

  Args:
    cmd: An array of strings as the command to run
    stdinput: An optional string as stdin
    env: An optional dictionary as the environment
    cwd: An optional string as the current working directory
    sudo: An optional boolean on whether to do the command via sudo
    sudo_password: An optional string of the password to use for sudo
    background: Launch command in background mode
    stream_output: An optional boolean on whether to send output to the screen
    timeout: An optional int or float; if >0, Exec() will stop waiting for
      output after timeout seconds and kill the process it started. Return code
      might be undefined, or -SIGTERM, use waitfor to make sure to obtain it.
      values <1 will be crudely rounded off because of select() sleep time.
    waitfor: An optional int or float, if >0, Exec() will wait waitfor seconds
      before asking for the process exit status one more time.
  Returns:
    Tuple: two strings and an integer: (stdout, stderr, returncode);
    stdout/stderr may also be None. If the process is set to launch in
    background mode, an instance of <subprocess.Popen object> is
    returned, in order to be able to read from its pipes *and* use poll() to
    check when it is finished.
  Raises:
    GmacpyutilException: If both stdinput and sudo_password are specified
    GmacpyutilException: If both sudo and background are specified
    GmacpyutilException: If both timeout and background, stream_output, sudo, or
      sudo_password, or stdinput are specified
    GmacpyutilException: If timeout is less than 0
    GmacpyutilException: If subprocess raises an OSError
  """
  if timeout and (background or stream_output or sudo or sudo_password or
                  stdinput):
    raise GmacpyutilException('timeout is not compatible with background, '
                              'stream_output, sudo, sudo_password, or '
                              'stdinput.')
  if waitfor and not timeout:
    raise GmacpyutilException('waitfor only valid with timeout.')
  if timeout < 0:
    raise GmacpyutilException('timeout must be greater than 0.')
  if stream_output:
    stdoutput = None
    stderror = None
  else:
    stdoutput = subprocess.PIPE
    stderror = subprocess.PIPE
  if sudo and not background:
    sudo_cmd = ['sudo']
    if sudo_password and not stdinput:
      # Set sudo to get password from stdin
      sudo_cmd.extend(['-S'])
      stdinput = sudo_password + '\n'
    elif sudo_password and stdinput:
      raise GmacpyutilException('stdinput and sudo_password are mutually '
                                'exclusive')
    else:
      sudo_cmd.extend(['-p', "%u's password is required for admin access: "])
    sudo_cmd.extend(cmd)
    cmd = sudo_cmd
  elif sudo and background:
    raise GmacpyutilException('sudo is not compatible with background.')
  environment = os.environ.copy()
  if env is not None:
    environment.update(env)
  try:
    task = subprocess.Popen(cmd, stdout=stdoutput, stderr=stderror,
                            stdin=subprocess.PIPE, env=environment, cwd=cwd)
  except OSError, e:
    raise GmacpyutilException('Could not execute: %s' % e.strerror)
  if timeout == 0:
    # communicate() will wait until the process is finished, so if we are in
    # background mode, just send the input and take the pipe objects as output.
    if not background:
      (stdout, stderr) = task.communicate(input=stdinput)
      return (stdout, stderr, task.returncode)
    else:
      if stdinput:
        task.stdin.write(stdinput)
      return task
  else:
    # TODO(user): See if it's possible to pass stdinput when using a timeout
    inactive = 0
    stdoutput = []
    stderror = []
    SetFileNonBlocking(task.stdout)
    SetFileNonBlocking(task.stderr)
    returncode = None
    while returncode is None:
      rlist, _, _ = select.select([task.stdout, task.stderr], [], [], 1.0)
      if not rlist:
        inactive += 1
        if inactive >= timeout:
          logging.error('cmd has timed out: %s', cmd)
          logging.error('Sending SIGTERM to PID=%s', task.pid)
          os.kill(task.pid, signal.SIGTERM)
          break  # note: this is a hard timeout, we don't read() again
      else:
        inactive = 0
        for fd in rlist:
          if fd is task.stdout:
            stdoutput.append(fd.read())
          elif fd is task.stderr:
            stderror.append(fd.read())

      returncode = task.poll()

    # if the process was just killed, wait for waitfor seconds.
    if inactive >= timeout and waitfor > 0:
      time.sleep(waitfor)
    # attempt to obtain returncode one last chance
    returncode = task.poll()
    stdoutput = ''.join(stdoutput)
    stderror = ''.join(stderror)
    return (stdoutput, stderror, task.returncode)
def _RunProcess ( cmd , stdinput = None , env = None , cwd = None , sudo = False , sudo_password = None , background = False , stream_output = False , timeout = 0 , waitfor = 0 ) : if timeout and ( background or stream_output or sudo or sudo_password or stdinput ) : raise GmacpyutilException ( 'timeout is not compatible with background, ' 'stream_output, sudo, sudo_password, or ' 'stdinput.' ) if waitfor and not timeout : raise GmacpyutilException ( 'waitfor only valid with timeout.' ) if timeout < 0 : raise GmacpyutilException ( 'timeout must be greater than 0.' ) if stream_output : stdoutput = None stderror = None else : stdoutput = subprocess . PIPE stderror = subprocess . PIPE if sudo and not background : sudo_cmd = [ 'sudo' ] if sudo_password and not stdinput : # Set sudo to get password from stdin sudo_cmd . extend ( [ '-S' ] ) stdinput = sudo_password + '\n' elif sudo_password and stdinput : raise GmacpyutilException ( 'stdinput and sudo_password are mutually ' 'exclusive' ) else : sudo_cmd . extend ( [ '-p' , "%u's password is required for admin access: " ] ) sudo_cmd . extend ( cmd ) cmd = sudo_cmd elif sudo and background : raise GmacpyutilException ( 'sudo is not compatible with background.' ) environment = os . environ . copy ( ) if env is not None : environment . update ( env ) try : task = subprocess . Popen ( cmd , stdout = stdoutput , stderr = stderror , stdin = subprocess . PIPE , env = environment , cwd = cwd ) except OSError , e : raise GmacpyutilException ( 'Could not execute: %s' % e . strerror ) if timeout == 0 : # communicate() will wait until the process is finished, so if we are in # background mode, just send the input and take the pipe objects as output. if not background : ( stdout , stderr ) = task . communicate ( input = stdinput ) return ( stdout , stderr , task . returncode ) else : if stdinput : task . stdin . write ( stdinput ) return task else : # TODO(user): See if it's possible to pass stdinput when using a timeout inactive = 0 stdoutput = [ ] stderror = [ ] SetFileNonBlocking ( task . stdout ) SetFileNonBlocking ( task . stderr ) returncode = None while returncode is None : rlist , _ , _ = select . select ( [ task . stdout , task . stderr ] , [ ] , [ ] , 1.0 ) if not rlist : inactive += 1 if inactive >= timeout : logging . error ( 'cmd has timed out: %s' , cmd ) logging . error ( 'Sending SIGTERM to PID=%s' , task . pid ) os . kill ( task . pid , signal . SIGTERM ) break # note: this is a hard timeout, we don't read() again else : inactive = 0 for fd in rlist : if fd is task . stdout : stdoutput . append ( fd . read ( ) ) elif fd is task . stderr : stderror . append ( fd . read ( ) ) returncode = task . poll ( ) # if the process was just killed, wait for waitfor seconds. if inactive >= timeout and waitfor > 0 : time . sleep ( waitfor ) # attempt to obtain returncode one last chance returncode = task . poll ( ) stdoutput = '' . join ( stdoutput ) stderror = '' . join ( stderror ) return ( stdoutput , stderror , task . returncode )