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 _______________________________________________ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs