]> xenbits.xensource.com Git - libvirt.git/commitdiff
virsh: properly interleave shared stdout and stderr
authorEric Blake <eblake@redhat.com>
Fri, 19 Aug 2011 15:20:35 +0000 (09:20 -0600)
committerEric Blake <eblake@redhat.com>
Fri, 19 Aug 2011 15:22:22 +0000 (09:22 -0600)
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.

tests/undefine
tools/virsh.c

index 6c821ad5b34001c41fa2e136521ac42f1be66e5b..22d6c1491c7a88e0e2053b97c3510a45dfd1fe30 100755 (executable)
@@ -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
index 1c67150299611311df152b8e401e5d087d2e865f..7d849ec1adfcb328ceeb76fa9bea37cfaec2870f 100644 (file)
@@ -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);
 }