Richard W.M. Jones
2012-Mar-11 20:16 UTC
[Libguestfs] [PATCH] Coalesce printable characters in debug and trace messages (RHBZ#802109).
From: "Richard W.M. Jones" <rjones at redhat.com> --- src/events.c | 25 +++++++++++++++++-------- 1 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/events.c b/src/events.c index f707e0b..9a1ca76 100644 --- a/src/events.c +++ b/src/events.c @@ -120,8 +120,7 @@ guestfs___call_callbacks_message (guestfs_h *g, uint64_t event, event == GUESTFS_EVENT_TRACE) && (g->verbose || event == GUESTFS_EVENT_TRACE)) { int from_appliance = event == GUESTFS_EVENT_APPLIANCE; - size_t i; - char c; + size_t i, i0; /* APPLIANCE => <buf> * LIBRARY => libguestfs: <buf>\n @@ -147,13 +146,23 @@ guestfs___call_callbacks_message (guestfs_h *g, uint64_t event, * Case 2: Messages from other sources: These messages should NOT * contain \n or \r. If they do, it is escaped. However we also * need to print a real end of line after these messages. + * + * RHBZ#802109: Because stderr is usually not buffered, avoid + * single 'putc' calls (which translate to a 1 byte write), and + * try to send longest possible strings in single fwrite calls + * (thanks to Jim Meyering for the basic approach). */ +#define NO_ESCAPING(c) \ + (c_isprint ((c)) || (from_appliance && ((c) == '\n' || (c) == '\r'))) + for (i = 0; i < buf_len; ++i) { - c = buf[i]; - if (c_isprint (c) || (from_appliance && (c == '\n' || c == '\r'))) - putc (c, stderr); - else { - switch (c) { + if (NO_ESCAPING (buf[i])) { + i0 = i; + while (i < buf_len && NO_ESCAPING (buf[i])) + ++i; + fwrite (&buf[i0], 1, i-i0, stderr); + } else { + switch (buf[i]) { case '\0': fputs ("\\0", stderr); break; case '\a': fputs ("\\a", stderr); break; case '\b': fputs ("\\b", stderr); break; @@ -163,7 +172,7 @@ guestfs___call_callbacks_message (guestfs_h *g, uint64_t event, case '\t': fputs ("\\t", stderr); break; case '\v': fputs ("\\v", stderr); break; default: - fprintf (stderr, "\\x%x", (unsigned) c); + fprintf (stderr, "\\x%x", (unsigned) buf[i]); } } } -- 1.7.9.1
Jim Meyering
2012-Mar-12 07:31 UTC
[Libguestfs] [PATCH] Coalesce printable characters in debug and trace messages (RHBZ#802109).
Richard W.M. Jones wrote:> +#define NO_ESCAPING(c) \ > + (c_isprint ((c)) || (from_appliance && ((c) == '\n' || (c) == '\r'))) > + > for (i = 0; i < buf_len; ++i) { > - c = buf[i]; > - if (c_isprint (c) || (from_appliance && (c == '\n' || c == '\r'))) > - putc (c, stderr); > - else { > - switch (c) { > + if (NO_ESCAPING (buf[i])) { > + i0 = i; > + while (i < buf_len && NO_ESCAPING (buf[i])) > + ++i; > + fwrite (&buf[i0], 1, i-i0, stderr); > + } else { > + switch (buf[i]) { > case '\0': fputs ("\\0", stderr); break; > case '\a': fputs ("\\a", stderr); break; > case '\b': fputs ("\\b", stderr); break; > @@ -163,7 +172,7 @@ guestfs___call_callbacks_message (guestfs_h *g, uint64_t event, > case '\t': fputs ("\\t", stderr); break; > case '\v': fputs ("\\v", stderr); break; > default: > - fprintf (stderr, "\\x%x", (unsigned) c); > + fprintf (stderr, "\\x%x", (unsigned) buf[i]);ACK