[Libguestfs] [PATCH v7 25/29] daemon: Implement command flag CommandFlagFoldStdoutOnStderr.

Richard W.M. Jones rjones at redhat.com
Mon Jun 19 15:39:50 UTC 2017


Used to handle broken commands like parted, sgdisk which print errors
on stdout.
---
 daemon/utils.ml  | 19 ++++++++++++++-----
 daemon/utils.mli | 11 +++++++++--
 2 files changed, 23 insertions(+), 7 deletions(-)

diff --git a/daemon/utils.ml b/daemon/utils.ml
index 48f6b9c5c..808e575fd 100644
--- a/daemon/utils.ml
+++ b/daemon/utils.ml
@@ -25,9 +25,15 @@ let prog_exists prog =
   try ignore (which prog); true
   with Executable_not_found _ -> false
 
-let commandr prog args =
+type command_flag =
+  CommandFlagFoldStdoutOnStderr
+
+let commandr ?(flags = []) prog args =
+  let fold_stdout_on_stderr = List.mem CommandFlagFoldStdoutOnStderr flags in
+
   if verbose () then
-    eprintf "command: %s %s\n%!"
+    eprintf "command:%s %s %s\n%!"
+            (if fold_stdout_on_stderr then " fold-stdout-on-stderr" else "")
             prog (String.concat " " args);
 
   let argv = Array.of_list (prog :: args) in
@@ -43,7 +49,10 @@ let commandr prog args =
     (* Child process. *)
     dup2 stdin_fd stdin;
     close stdin_fd;
-    dup2 stdout_fd stdout;
+    if not fold_stdout_on_stderr then
+      dup2 stdout_fd stdout
+    else
+      dup2 stderr_fd stdout;
     close stdout_fd;
     dup2 stderr_fd stderr;
     close stderr_fd;
@@ -91,8 +100,8 @@ let commandr prog args =
 
   (r, stdout, stderr)
 
-let command prog args =
-  let r, stdout, stderr = commandr prog args in
+let command ?flags prog args =
+  let r, stdout, stderr = commandr ?flags prog args in
   if r <> 0 then
     failwithf "%s exited with status %d: %s" prog r stderr;
   stdout
diff --git a/daemon/utils.mli b/daemon/utils.mli
index a1f956be3..d3c8bdf4d 100644
--- a/daemon/utils.mli
+++ b/daemon/utils.mli
@@ -60,7 +60,14 @@ val proc_unmangle_path : string -> string
 (** Reverse kernel path escaping done in fs/seq_file.c:mangle_path.
     This is inconsistently used for /proc fields. *)
 
-val command : string -> string list -> string
+type command_flag =
+  CommandFlagFoldStdoutOnStderr
+    (** For broken external commands that send error messages to stdout
+        (hello, parted) but that don't have any useful stdout information,
+        use this flag to capture the error messages in the [stderr]
+        buffer.  Nothing will be captured on stdout if you use this flag. *)
+
+val command : ?flags:command_flag list -> string -> string list -> string
 (** Run an external command without using the shell, and collect
     stdout and stderr separately.  Returns stdout if the command
     runs successfully.
@@ -68,7 +75,7 @@ val command : string -> string list -> string
     On failure of the command, this throws an exception containing
     the stderr from the command. *)
 
-val commandr : string -> string list -> (int * string * string)
+val commandr : ?flags:command_flag list -> string -> string list -> (int * string * string)
 (** Run an external command without using the shell, and collect
     stdout and stderr separately.
 
-- 
2.13.0




More information about the Libguestfs mailing list