[libvirt] [PATCH] virsh: properly interleave shared stdout and stderr

Laine Stump laine at laine.org
Fri Aug 19 18:34:45 UTC 2011


On 08/19/2011 11:23 AM, Eric Blake wrote:
> Without this patch, invoking 'virsh>file 2>&1' results in
> error messages appearing before normal output, even if they
> occurred later in time than the normal output (since stderr
> is unbuffered, but stdout waits until a full buffer).
>
> * tools/virsh.c (print_job_progress, vshError): Flush between
> stream transitions.
> * tests/undefine: Test it.
> ---
>
> This fixes the bug I mentioned here:
> https://www.redhat.com/archives/libvir-list/2011-August/msg00891.html
>
>   tests/undefine |    5 +----
>   tools/virsh.c  |    8 ++++++++
>   2 files changed, 9 insertions(+), 4 deletions(-)
>
> diff --git a/tests/undefine b/tests/undefine
> index 6c821ad..22d6c14 100755
> --- a/tests/undefine
> +++ b/tests/undefine
> @@ -58,17 +58,14 @@ compare exp out || fail=1
>
>   # Succeed, now: first shut down, then undefine, both via name.
>   $abs_top_builddir/tools/virsh -q -c test:///default \
> -    'shutdown test; undefine test; dominfo test'>  out 2>  err
> +    'shutdown test; undefine test; dominfo test'>  out 2>&1
>   test $? = 1 || fail=1
>   cat<<\EOF>  expout || fail=1
>   Domain test is being shutdown
>   Domain test has been undefined
> -EOF
> -cat<<\EOF>  experr || fail=1
>   error: failed to get domain 'test'
>   error: Domain not found
>   EOF
>   compare expout out || fail=1
> -compare experr err || fail=1
>
>   (exit $fail); exit $fail
> diff --git a/tools/virsh.c b/tools/virsh.c
> index 1c67150..7d849ec 100644
> --- a/tools/virsh.c
> +++ b/tools/virsh.c
> @@ -4956,7 +4956,10 @@ print_job_progress(const char *label, unsigned long long remaining,
>           }
>       }
>
> +    /* see comments in vshError about why we must flush */
> +    fflush(stdout);
>       fprintf(stderr, "\r%s: [%3d %%]", label, progress);
> +    fflush(stderr);
>   }
>
>   static bool
> @@ -14336,6 +14339,10 @@ vshError(vshControl *ctl, const char *format, ...)
>           va_end(ap);
>       }
>
> +    /* Most output is to stdout, but if someone ran virsh 2>&1, then
> +     * printing to stderr will not interleave correctly with stdout
> +     * unless we flush between every transition between streams.  */
> +    fflush(stdout);
>       fputs(_("error: "), stderr);
>
>       va_start(ap, format);
> @@ -14345,6 +14352,7 @@ vshError(vshControl *ctl, const char *format, ...)
>       va_end(ap);
>
>       fprintf(stderr, "%s\n", NULLSTR(str));
> +    fflush(stderr);
>       VIR_FREE(str);
>   }


ACK.




More information about the libvir-list mailing list