From f343dbb9db3ceb8477900e5c17cc42d39f9004af Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Tue, 12 Apr 2016 01:07:59 -0400 Subject: stdio error handling is such a pain --- src/freenect-server.c | 28 ++++++++++++++++++++++------ src/multipart-replace.c | 37 +++++++++++++++++++------------------ 2 files changed, 41 insertions(+), 24 deletions(-) diff --git a/src/freenect-server.c b/src/freenect-server.c index 286455b..94f307c 100644 --- a/src/freenect-server.c +++ b/src/freenect-server.c @@ -44,6 +44,20 @@ void stop(int sig); exitcode = stat; \ stop(0); \ } while(0) +#define stdioerror(stream, name) do { \ + if (feof(stream)) { \ + error(0, 0, "%s: EOF", name); \ + } else { \ + if (ferror(stream)) { \ + fflush(stream); \ + error(0, errno, "%s", name); \ + } else { \ + error(0, 0, "%s: panic: neither feof nor ferror", name); \ + } \ + exitcode = EXIT_FAILURE; \ + } \ + stop(0); \ + } while(0) struct mpjpg_encoder { struct jpeg_error_mgr jpeg_encoder_err; @@ -96,12 +110,13 @@ void write_imageframe(const char *name, FILE *stream, struct mpjpg_encoder *e, J "Content-length: %lu\r\n" "\r\n", e->jpeg_len) < 1) - threaderror(EXIT_FAILURE, ferror(stream), "%s: writing header", name); + stdioerror(stream, name); if (fwrite(e->jpeg_buf, e->jpeg_len, 1, stream) < 1) - threaderror(EXIT_FAILURE, ferror(stream), "%s: writing body", name); + stdioerror(stream, name); if (fwrite("\r\n", 2, 1, stream) < 1) - threaderror(EXIT_FAILURE, ferror(stream), "%s: writing footer", name); - fflush(stream); + stdioerror(stream, name); + if (fflush(stream) != 0) + stdioerror(stream, name); } void handle_accel(freenect_device *dev UNUSED, freenect_raw_tilt_state* data) { @@ -141,9 +156,10 @@ void handle_accel(freenect_device *dev UNUSED, freenect_raw_tilt_state* data) { "\r\n" "%s\r\n", len, json) < 0) - threaderror(EXIT_FAILURE, ferror(accel_stream), "accel.mjson: write"); + stdioerror(accel_stream, "accel.mjson"); free(json); - fflush(accel_stream); + if (fflush(accel_stream) != 0) + threaderror(EXIT_FAILURE, errno, "accel.mjson"); } uint8_t depth_rgb[640*480*3]; diff --git a/src/multipart-replace.c b/src/multipart-replace.c index 1f7a75c..658d634 100644 --- a/src/multipart-replace.c +++ b/src/multipart-replace.c @@ -27,7 +27,7 @@ #include "multipart-replace.h" #include "util.h" -#define error(stat, errnum, ...) do { \ +#define threaderror(stat, errnum, ...) do { \ error(0, errnum, __VA_ARGS__); \ ret = stat; \ goto end; \ @@ -36,9 +36,9 @@ if (feof(stream)) { \ error(0, 0, "%s: EOF", name); \ } else { \ - int err = ferror(stream); \ - if (err != 0) { \ - error(0, err, "%s", name); \ + if (ferror(stream)) { \ + fflush(stream); \ + error(0, errno, "%s", name); \ } else { \ error(0, 0, "%s: panic: neither feof nor ferror", name); \ } \ @@ -95,7 +95,7 @@ int multipart_replace_reader(struct multipart_replace_stream *s, int fd, const c } while (strcmp(line_buf, "\r\n") == 0); /* make sure it matches the boundary separator */ if (strcmp(line_buf, boundary) != 0) - error(EXIT_FAILURE, 0, "line does not match boundary: \"%s\"", line_buf); + threaderror(EXIT_FAILURE, 0, "line does not match boundary: \"%s\"", line_buf); /* read the frame header (MIME headers) */ s->back->len = 0; do { @@ -114,7 +114,7 @@ int multipart_replace_reader(struct multipart_replace_stream *s, int fd, const c } while (strcmp(line_buf, "\r\n") != 0); /* make sure that it included a Content-length header */ if (content_length < 0) - error(EXIT_FAILURE, 0, "did not get frame length"); + threaderror(EXIT_FAILURE, 0, "did not get frame length"); /* read the frame contents */ if ((ssize_t)s->back->cap < s->back->len + content_length) s->back->buf = xrealloc(s->back->buf, s->back->cap = s->back->len + content_length); @@ -152,20 +152,21 @@ int multipart_replace_writer(struct multipart_replace_stream *s, int fd, const c if (myframe.cap < (size_t)s->front->len) myframe.buf = xrealloc(myframe.buf, myframe.cap = s->front->len); memcpy(myframe.buf, s->front->buf, myframe.len = s->front->len); - pthread_rwlock_unlock(&s->frontlock); - if (myframe.len != 0) { - /* send the frame to the client */ - if (fwrite(boundary, boundary_len, 1, stream) < 1) - stdioerror(stream, "dst <- boundary"); - if (fwrite(myframe.buf, myframe.len, 1, stream) < 1) - stdioerror(stream, "dst <- frame"); - /* send a blank line for pleasantness */ - if (fwrite("\r\n", 2, 1, stream) < 1) - stdioerror(stream, "dst <- nl"); - fflush(stream); - } + if (myframe.len == 0) + threaderror(EXIT_FAILURE, 0, "got empty frame"); + + /* send the frame to the client */ + if (fwrite(boundary, boundary_len, 1, stream) < 1) + stdioerror(stream, "dst <- boundary"); + if (fwrite(myframe.buf, myframe.len, 1, stream) < 1) + stdioerror(stream, "dst <- frame"); + /* send a blank line for pleasantness */ + if (fwrite("\r\n", 2, 1, stream) < 1) + stdioerror(stream, "dst <- nl"); + if (fflush(stream) != 0) + threaderror(EXIT_FAILURE, errno, "dst"); } end: free(boundary); -- cgit v1.2.3