From 902b9f3ff9d45ff4dccc35b1acaa3311865656ad Mon Sep 17 00:00:00 2001 Message-Id: <902b9f3ff9d45ff4dccc35b1acaa3311865656ad.1716268241.git.mdw@distorted.org.uk> From: Mark Wooding Date: Sun, 17 Nov 2013 11:21:47 +0000 Subject: [PATCH] More general error handling for sinks Organization: Straylight/Edgeware From: Richard Kettlewell --- cgi/disorder-cgi.h | 2 +- lib/asprintf.c | 2 +- lib/fprintf.c | 1 + lib/printf.c | 1 + lib/sink.c | 31 +++++++++++++++++++++++++++++-- lib/sink.h | 25 +++++++++++++++++++++++-- lib/snprintf.c | 1 + 7 files changed, 57 insertions(+), 6 deletions(-) diff --git a/cgi/disorder-cgi.h b/cgi/disorder-cgi.h index e9deab2..168ba9b 100644 --- a/cgi/disorder-cgi.h +++ b/cgi/disorder-cgi.h @@ -30,6 +30,7 @@ #include #include +#include "log.h" #include "mem.h" #include "kvp.h" #include "queue.h" @@ -46,7 +47,6 @@ #include "table.h" #include "vector.h" #include "url.h" -#include "log.h" #include "inputline.h" #include "split.h" #include "mime.h" diff --git a/lib/asprintf.c b/lib/asprintf.c index fd9fa6c..44be789 100644 --- a/lib/asprintf.c +++ b/lib/asprintf.c @@ -24,10 +24,10 @@ #include #include "printf.h" +#include "log.h" #include "sink.h" #include "mem.h" #include "vector.h" -#include "log.h" /** @brief vasprintf() workalike without encoding errors * diff --git a/lib/fprintf.c b/lib/fprintf.c index 3227f12..c88dcdd 100644 --- a/lib/fprintf.c +++ b/lib/fprintf.c @@ -25,6 +25,7 @@ #include #include "printf.h" +#include "log.h" #include "sink.h" #include "mem.h" diff --git a/lib/printf.c b/lib/printf.c index 15cd8ad..9f1b57a 100644 --- a/lib/printf.c +++ b/lib/printf.c @@ -29,6 +29,7 @@ #include #include "printf.h" +#include "log.h" #include "sink.h" #include "vacopy.h" diff --git a/lib/sink.c b/lib/sink.c index 7a74640..84b9c25 100644 --- a/lib/sink.c +++ b/lib/sink.c @@ -1,6 +1,6 @@ /* * This file is part of DisOrder - * Copyright (C) 2004, 2007, 2008 Richard Kettlewell + * Copyright (C) 2004, 2007-9, 2013 Richard Kettlewell * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -26,8 +26,8 @@ #include "mem.h" #include "vector.h" -#include "sink.h" #include "log.h" +#include "sink.h" #include "printf.h" /** @brief Formatted output to a sink @@ -55,6 +55,14 @@ int sink_printf(struct sink *s, const char *fmt, ...) { return n; } +static int sink_generic_flush(struct sink attribute((unused)) *s) { + return 0; +} + +static int sink_generic_error(struct sink attribute((unused)) *s) { + return 0; +} + /* stdio sink *****************************************************************/ /** @brief Sink that writes to a stdio @c FILE */ @@ -67,6 +75,8 @@ struct stdio_sink { /** @brief Stream to write to */ FILE *fp; + + int error; }; /** @brief Reinterpret a @ref sink as a @ref stdio_sink */ @@ -76,6 +86,7 @@ struct stdio_sink { static int sink_stdio_write(struct sink *s, const void *buffer, int nbytes) { int n = fwrite(buffer, 1, nbytes, S(s)->fp); if(n < nbytes) { + S(s)->error = errno; if(S(s)->name) disorder_fatal(errno, "error writing to %s", S(s)->name); else @@ -84,6 +95,10 @@ static int sink_stdio_write(struct sink *s, const void *buffer, int nbytes) { return n; } +static int sink_stdio_error(struct sink *s) { + return S(s)->error; +} + /** @brief Create a sink that writes to a stdio stream * @param name Filename for use in error messages * @param fp Stream to write to @@ -93,6 +108,9 @@ struct sink *sink_stdio(const char *name, FILE *fp) { struct stdio_sink *s = xmalloc(sizeof *s); s->s.write = sink_stdio_write; + s->s.flush = sink_generic_flush; + s->s.error = sink_stdio_error; + s->s.eclass = ec_errno; s->name = name; s->fp = fp; return (struct sink *)s; @@ -122,6 +140,9 @@ struct sink *sink_dynstr(struct dynstr *output) { struct dynstr_sink *s = xmalloc(sizeof *s); s->s.write = sink_dynstr_write; + s->s.flush = sink_generic_flush; + s->s.error = sink_generic_error; + s->s.eclass = ec_errno; s->d = output; return (struct sink *)s; } @@ -139,6 +160,9 @@ struct sink *sink_discard(void) { struct sink *s = xmalloc(sizeof *s); s->write = sink_discard_write; + s->flush = sink_generic_flush; + s->error = sink_generic_error; + s->eclass = ec_errno; return s; } @@ -155,6 +179,9 @@ struct sink *sink_error(void) { struct sink *s = xmalloc(sizeof *s); s->write = sink_error_write; + s->flush = sink_generic_flush; + s->error = sink_generic_error; + s->eclass = ec_errno; return s; } diff --git a/lib/sink.h b/lib/sink.h index 5d09c18..d3ab999 100644 --- a/lib/sink.h +++ b/lib/sink.h @@ -1,6 +1,6 @@ /* * This file is part of DisOrder - * Copyright (C) 2004, 2007, 2008 Richard Kettlewell + * Copyright (C) 2004, 2007, 2008, 2013 Richard Kettlewell * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -40,6 +40,20 @@ struct sink { * @return non-negative on success, -1 on error */ int (*write)(struct sink *s, const void *buffer, int nbytes); + + /** @brief Flush callback + * @param s Sink to write to + * @return non-negative on success, -1 on error + */ + int (*flush)(struct sink *s); + + /** @brief Error callback + * @param s Sink + * @return Last error code + */ + int (*error)(struct sink *s); + + enum error_class eclass; }; struct sink *sink_stdio(const char *name, FILE *fp); @@ -80,6 +94,10 @@ static inline int sink_writes(struct sink *s, const char *str) { return s->write(s, str, strlen(str)); } +static inline int sink_flush(struct sink *s) { + return s->flush(s); +} + /** @brief Write one byte to a sink * @param s Sink to write to * @param c Byte to write (as a @c char) @@ -89,8 +107,11 @@ static inline int sink_writec(struct sink *s, char c) { return s->write(s, &c, 1); } -#endif /* SINK_H */ +static inline int sink_err(struct sink *s) { + return s->error(s); +} +#endif /* SINK_H */ /* Local Variables: diff --git a/lib/snprintf.c b/lib/snprintf.c index f272dc7..27ac595 100644 --- a/lib/snprintf.c +++ b/lib/snprintf.c @@ -28,6 +28,7 @@ #include #include "printf.h" +#include "log.h" #include "sink.h" /** @brief A @ref sink that stores to a fixed buffer -- [mdw]