X-Git-Url: http://git.annexia.org/?a=blobdiff_plain;f=src%2Fevents.c;h=aa30fd2e4ee67f74657d89a997e222e8d1302b31;hb=d28f8f4cc36b42ace02b8c02b80a945315fdbf24;hp=159862a4690b91b059b9bff011c958bf3aa4b171;hpb=4e0cf4dbf8a8a96288f70114fdc3939da0aa7ad1;p=libguestfs.git diff --git a/src/events.c b/src/events.c index 159862a..aa30fd2 100644 --- a/src/events.c +++ b/src/events.c @@ -26,7 +26,9 @@ #include #include #include +#include +#include "c-ctype.h" #include "ignore-value.h" #include "guestfs.h" @@ -115,9 +117,9 @@ guestfs___call_callbacks_message (guestfs_h *g, uint64_t event, * override print-on-stderr simply by registering a callback. */ if (count == 0 && (g->verbose || event == GUESTFS_EVENT_TRACE)) { - const char *prefix = "libguestfs: "; - const char *trace = "trace: "; - const char *nl = "\n"; + int from_appliance = event == GUESTFS_EVENT_APPLIANCE; + size_t i; + char c; /* APPLIANCE => * LIBRARY => libguestfs: \n @@ -125,18 +127,47 @@ guestfs___call_callbacks_message (guestfs_h *g, uint64_t event, */ if (event != GUESTFS_EVENT_APPLIANCE) - ignore_value (write (STDERR_FILENO, prefix, strlen (prefix))); + fputs ("libguestfs: ", stderr); if (event == GUESTFS_EVENT_TRACE) - ignore_value (write (STDERR_FILENO, trace, strlen (trace))); - - ignore_value (write (STDERR_FILENO, buf, buf_len)); - - /* Messages from the appliance already contain \n characters, others - * need this to be appended. + fputs ("trace: ", stderr); + + /* Special or non-printing characters in the buffer must be + * escaped (RHBZ#731744). The buffer can contain any 8 bit + * character, even \0. + * + * Handling of \n and \r characters is complex: + * + * Case 1: Messages from the appliance: These messages already + * contain \n and \r characters at logical positions, so we just + * echo those out directly. + * + * 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. */ - if (event != GUESTFS_EVENT_APPLIANCE) - ignore_value (write (STDERR_FILENO, nl, strlen (nl))); + 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) { + case '\0': fputs ("\\0", stderr); break; + case '\a': fputs ("\\a", stderr); break; + case '\b': fputs ("\\b", stderr); break; + case '\f': fputs ("\\f", stderr); break; + case '\n': fputs ("\\n", stderr); break; + case '\r': fputs ("\\r", stderr); break; + case '\t': fputs ("\\t", stderr); break; + case '\v': fputs ("\\v", stderr); break; + default: + fprintf (stderr, "\\x%x", (unsigned) c); + } + } + } + + if (!from_appliance) + putc ('\n', stderr); } }