[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