Added return_stderr support to cmd_fnc.

Change-Id: Id99f70b9411f95ce98bd6dd0ab40e77dc9b96393
Signed-off-by: Michael Walsh <micwalsh@us.ibm.com>
diff --git a/lib/gen_cmd.py b/lib/gen_cmd.py
index b5c5341..57cd65b 100644
--- a/lib/gen_cmd.py
+++ b/lib/gen_cmd.py
@@ -26,29 +26,39 @@
             test_mode=None,
             debug=0,
             print_output=1,
-            show_err=1):
+            show_err=1,
+            return_stderr=0):
 
     r"""
-    Run the given command in a shell and return the shell return code.
+    Run the given command in a shell and return the shell return code and the
+    output.
 
     Description of arguments:
     cmd_buf                         The command string to be run in a shell.
     quiet                           Indicates whether this function should run
-                                    the pissuing()
-                  function prints an "Issuing: <cmd string>" to stdout.
+                                    the print_issuing() function which prints
+                                    "Issuing: <cmd string>" to stdout.
     test_mode                       If test_mode is set, this function will
-                                    not actually run
-                  the command.
+                                    not actually run the command.  If
+                                    print_output is set, it will print
+                                    "(test_mode) Issuing: <cmd string>" to
+                                    stdout.
     debug                           If debug is set, this function will print
                                     extra debug info.
     print_output                    If this is set, this function will print
-                                    the stdout/stderr
-                  generated by the shell command.
+                                    the stdout/stderr generated by the shell
+                                    command.
     show_err                        If show_err is set, this function will
-                                    print a standardized
-                  error report if the shell command returns non-zero.
+                                    print a standardized error report if the
+                                    shell command returns non-zero.
+    return_stderr                   If return_stderr is set, this function
+                                    will process the stdout and stderr streams
+                                    from the shell command separately.  It
+                                    will also return stderr in addition to the
+                                    return code and the stdout.
     """
 
+    # Determine default values.
     quiet = int(gm.global_default(quiet, 0))
     test_mode = int(gm.global_default(test_mode, 0))
 
@@ -63,14 +73,32 @@
         gp.pissuing(cmd_buf, test_mode)
 
     if test_mode:
-        return 0, ""
+        if return_stderr:
+            return 0, "", ""
+        else:
+            return 0, ""
+
+    if return_stderr:
+        err_buf = ""
+        stderr = subprocess.PIPE
+    else:
+        stderr = subprocess.STDOUT
 
     sub_proc = subprocess.Popen(cmd_buf,
                                 bufsize=1,
                                 shell=True,
                                 stdout=subprocess.PIPE,
-                                stderr=subprocess.STDOUT)
+                                stderr=stderr)
     out_buf = ""
+    if return_stderr:
+        for line in sub_proc.stderr:
+            err_buf += line
+            if not print_output:
+                continue
+            if robot_env:
+                grp.rprint(line)
+            else:
+                sys.stdout.write(line)
     for line in sub_proc.stdout:
         out_buf += line
         if not print_output:
@@ -84,14 +112,19 @@
     sub_proc.communicate()
     shell_rc = sub_proc.returncode
     if shell_rc != 0 and show_err:
-        if robot_env:
-            grp.rprint_error_report("The prior command failed.\n" +
-                                    gp.sprint_var(shell_rc, 1))
-        else:
-            gp.print_error_report("The prior command failed.\n" +
-                                  gp.sprint_var(shell_rc, 1))
+        err_msg = "The prior command failed.\n" + gp.sprint_var(shell_rc, 1)
+        if not print_output:
+            err_msg += "out_buf:\n" + out_buf
 
-    return shell_rc, out_buf
+        if robot_env:
+            grp.rprint_error_report(err_msg)
+        else:
+            gp.print_error_report(err_msg)
+
+    if return_stderr:
+        return shell_rc, out_buf, err_buf
+    else:
+        return shell_rc, out_buf
 
 ###############################################################################
 
@@ -101,7 +134,8 @@
               quiet=None,
               debug=None,
               print_output=1,
-              show_err=1):
+              show_err=1,
+              return_stderr=0):
 
     r"""
     Call cmd_fnc with test_mode=0.  See cmd_fnc (above) for details.
@@ -110,7 +144,8 @@
     """
 
     return cmd_fnc(cmd_buf, test_mode=0, quiet=quiet, debug=debug,
-                   print_output=print_output, show_err=show_err)
+                   print_output=print_output, show_err=show_err,
+                   return_stderr=return_stderr)
 
 ###############################################################################