[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

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



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.


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]