diff --git a/boilerplate/cairo-boilerplate.c b/boilerplate/cairo-boilerplate.c index f7146b745..039fb3dee 100644 --- a/boilerplate/cairo-boilerplate.c +++ b/boilerplate/cairo-boilerplate.c @@ -746,6 +746,24 @@ cairo_boilerplate_open_any2ppm (const char *filename, return popen (command, "r"); } +static cairo_bool_t +freadn (char *buf, int len, FILE *file) +{ + int ret; + + while (len) { + ret = fread (buf, 1, len, file); + if (ret != len) { + if (ferror (file) || feof (file)) + return FALSE; + } + len -= ret; + buf += len; + } + + return TRUE; +} + cairo_surface_t * cairo_boilerplate_image_surface_create_from_ppm_stream (FILE *file) { @@ -780,18 +798,18 @@ cairo_boilerplate_image_surface_create_from_ppm_stream (FILE *file) unsigned char *buf = data + y *stride; switch (format) { case '7': - if (fread (buf, 4, width, file) != (size_t) width) + if (! freadn (buf, 4 * width, file)) goto FAIL; break; case '6': for (x = 0; x < width; x++) { - if (fread (buf, 1, 3, file) != 3) + if (! freadn (buf, 3, file)) goto FAIL; buf += 4; } break; case '5': - if (fread (buf, 1, width, file) != (size_t) width) + if (! freadn (buf, width, file)) goto FAIL; break; } diff --git a/test/any2ppm.c b/test/any2ppm.c index bca35f3cd..412bbb8bc 100644 --- a/test/any2ppm.c +++ b/test/any2ppm.c @@ -79,6 +79,7 @@ #include #include #include +#include #define SOCKET_PATH "./.any2ppm" #define TIMEOUT 60000 /* 60 seconds */ @@ -88,6 +89,30 @@ #define ARRAY_LENGTH(A) (sizeof (A) / sizeof (A[0])) +static int +_writen (int fd, char *buf, int len) +{ + while (len) { + int ret; + + ret = write (fd, buf, len); + if (ret == -1) { + int err = errno; + switch (err) { + case EINTR: + case EAGAIN: + continue; + default: + return 0; + } + } + len -= ret; + buf += ret; + } + + return 1; +} + static int _write (int fd, char *buf, int maxlen, int buflen, @@ -110,8 +135,9 @@ _write (int fd, src += len; if (buflen == maxlen) { - if (write (fd, buf, maxlen) != maxlen) + if (! _writen (fd, buf, buflen)) return -1; + buflen = 0; } } @@ -180,10 +206,8 @@ write_ppm (cairo_surface_t *surface, int fd) return "write failed"; } - if (len) { - if (write (fd, buf, len) != len) - return "write failed"; - } + if (len && ! _writen (fd, buf, len)) + return "write failed"; return NULL; } @@ -548,8 +572,20 @@ any2ppm_daemon (void) if (_getline (fd, &line, &len) != -1) { char *argv[10]; - if (split_line (line, argv, ARRAY_LENGTH (argv)) > 0) - convert (argv, fd); + if (split_line (line, argv, ARRAY_LENGTH (argv)) > 0) { + const char *err; + + err = convert (argv, fd); + if (err != NULL) { + FILE *file = fopen (".any2ppm.errors", "a"); + if (file != NULL) { + fprintf (file, + "Failed to convert '%s': %s\n", + argv[0], err); + fclose (file); + } + } + } } close (fd); }