def execCmdThruIUCV(rh, userid, strCmd, hideInLog=[]):
    """
    Send a command to a virtual machine using IUCV.

    Input:
       Request Handle
       Userid of the target virtual machine
       Command string to send
       (Optional) List of strCmd words (by index) to hide in
          sysLog by replacing the word with "<hidden>".

    Output:
       Dictionary containing the following:
          overallRC - overall return code, 0: success, 2: failure
          rc        - RC returned from iucvclnt if overallRC != 0.
          rs        - RS returned from iucvclnt if overallRC != 0.
          errno     - Errno returned from iucvclnt if overallRC != 0.
          response  - Output of the iucvclnt command or this routine.

    Notes:
       1) This routine does not use the Request Handle printLn function.
          This is because an error might be expected and we might desire
          to suppress it.  Instead, any error messages are put in the
          response dictionary element that is returned.
    """
    if len(hideInLog) == 0:
        rh.printSysLog("Enter vmUtils.execCmdThruIUCV, userid: " +
                       userid + " cmd: " + strCmd)
    else:
        logCmd = strCmd.split(' ')
        for i in hideInLog:
            logCmd[i] = '<hidden>'
        rh.printSysLog("Enter vmUtils.execCmdThruIUCV, userid: " +
                       userid + " cmd: " + ' '.join(logCmd))

    iucvpath = '/opt/zthin/bin/IUCV/'
    results = {
              'overallRC': 0,
              'rc': 0,
              'rs': 0,
              'errno': 0,
              'response': [],
             }

    cmd = ['sudo',
           iucvpath + "iucvclnt",
           userid,
           strCmd]
    try:
        results['response'] = subprocess.check_output(
                cmd,
                stderr=subprocess.STDOUT,
                close_fds=True)
        if isinstance(results['response'], bytes):
            results['response'] = bytes.decode(results['response'])
    except CalledProcessError as e:
        msg = []
        results['overallRC'] = 2
        results['rc'] = e.returncode
        output = bytes.decode(e.output)

        match = re.search('Return code (.+?),', output)
        if match:
            try:
                results['rc'] = int(match.group(1))
            except ValueError:
                # Return code in response from IUCVCLNT is not an int.
                msg = msgs.msg['0311'][1] % (modId, userid, strCmd,
                    results['rc'], match.group(1), output)

        if not msg:
            # We got the rc. Now, get the rs.
            match = re.search('Reason code (.+?)\.', output)
            if match:
                try:
                    results['rs'] = int(match.group(1))
                except ValueError:
                    # Reason code in response from IUCVCLNT is not an int.
                    msg = msgs.msg['0312'][1] % (modId, userid, strCmd,
                        results['rc'], match.group(1), output)

        if msg:
            # Already produced an error message.
            pass
        elif results['rc'] == 1:
            # Command was not authorized or a generic Linux error.
            msg = msgs.msg['0313'][1] % (modId, userid, strCmd,
                results['rc'], results['rs'], output)
        elif results['rc'] == 2:
            # IUCV client parameter error.
            msg = msgs.msg['0314'][1] % (modId, userid, strCmd,
                results['rc'], results['rs'], output)
        elif results['rc'] == 4:
            # IUCV socket error
            msg = msgs.msg['0315'][1] % (modId, userid, strCmd,
                results['rc'], results['rs'], output)
        elif results['rc'] == 8:
            # Executed command failed
            msg = msgs.msg['0316'][1] % (modId, userid, strCmd,
                results['rc'], results['rs'], output)
        elif results['rc'] == 16:
            # File Transport failed
            msg = msgs.msg['0317'][1] % (modId, userid, strCmd,
                results['rc'], results['rs'], output)
        elif results['rc'] == 32:
            # IUCV server file was not found on this system.
            msg += msgs.msg['0318'][1] % (modId, userid, strCmd,
                results['rc'], results['rs'], output)
        else:
            # Unrecognized IUCV client error
            msg = msgs.msg['0319'][1] % (modId, userid, strCmd,
                results['rc'], results['rs'], output)
        results['response'] = msg

    except Exception as e:
        # Other exceptions from this system (i.e. not the managed system).
        results = msgs.msg['0421'][0]
        msg = msgs.msg['0421'][1] % (modId, strCmd,
            type(e).__name__, str(e))
        results['response'] = msg

    rh.printSysLog("Exit vmUtils.execCmdThruIUCV, rc: " +
                   str(results['rc']))
    return results
Send a command to a virtual machine using IUCV.

    Input:
       Request Handle
       Userid of the target virtual machine
       Command string to send
       (Optional) List of strCmd words (by index) to hide in
          sysLog by replacing the word with "<hidden>".

    Output:
       Dictionary containing the following:
          overallRC - overall return code, 0: success, 2: failure
          rc        - RC returned from iucvclnt if overallRC != 0.
          rs        - RS returned from iucvclnt if overallRC != 0.
          errno     - Errno returned from iucvclnt if overallRC != 0.
          response  - Output of the iucvclnt command or this routine.

    Notes:
       1) This routine does not use the Request Handle printLn function.
          This is because an error might be expected and we might desire
          to suppress it.  Instead, any error messages are put in the
          response dictionary element that is returned.