summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2008-09-25 00:16:45 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2008-09-26 13:42:28 +0100
commitf2c484d73ce61012a2d9925f15b55e7c51e34b85 (patch)
treec5278fc614cfd707e5a2c3f0b85711b7af65985c
parent681424cbaf94556bf1804547b42ad642c0a066ab (diff)
downloadcairo-f2c484d73ce61012a2d9925f15b55e7c51e34b85.tar.gz
[test/any2ppm] Handle short reads/writes.
No excuse other than simple laziness - it manifested itself with random "error whilst reading" failures.
-rw-r--r--boilerplate/cairo-boilerplate.c24
-rw-r--r--test/any2ppm.c50
2 files changed, 64 insertions, 10 deletions
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 @@ POPEN:
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 <sys/socket.h>
#include <sys/poll.h>
#include <sys/un.h>
+#include <errno.h>
#define SOCKET_PATH "./.any2ppm"
#define TIMEOUT 60000 /* 60 seconds */
@@ -89,6 +90,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,
const unsigned char *src, int srclen)
@@ -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);
}