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

Eric Blake eblake at redhat.com
Fri Aug 19 15:23:44 UTC 2011


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);
 }

-- 
1.7.4.4




More information about the libvir-list mailing list