From 302e423dc1a6dd8f72e126ec3279a14938da625a Mon Sep 17 00:00:00 2001 From: Sami Kerola Date: Wed, 4 Apr 2012 19:22:08 +0200 Subject: include: add stream error checking facility The close_stream() is copied from GNU lib. Inspiration to do this is talk by Jim Meyering - Goodbye World! The perils of relying on output streams in C. Reference: http://www.irill.org/events/ghm-gnu-hackers-meeting/videos/jim-meyering-goodbye-world-the-perils-of-relying-on-output-streams-in-c Signed-off-by: Sami Kerola --- include/closestream.h | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 include/closestream.h (limited to 'include/closestream.h') diff --git a/include/closestream.h b/include/closestream.h new file mode 100644 index 000000000..fb507eab8 --- /dev/null +++ b/include/closestream.h @@ -0,0 +1,41 @@ +#ifndef UTIL_LINUX_CLOSESTREAM_H +#define UTIL_LINUX_CLOSESTREAM_H + +#include +#include +#include + +#include "c.h" +#include "nls.h" + +static inline int +close_stream(FILE * stream) +{ + const int some_pending = (__fpending(stream) != 0); + const int prev_fail = (ferror(stream) != 0); + const int fclose_fail = (fclose(stream) != 0); + if (prev_fail || (fclose_fail && (some_pending || errno != EBADF))) { + if (!fclose_fail) + errno = 0; + return EOF; + } + return 0; +} + +/* Meant to be used atexit(close_stdout); */ +static inline void +close_stdout(void) +{ + if (close_stream(stdout) != 0 && !(errno == EPIPE)) { + if (errno) + warn(_("write error")); + else + warnx(_("write error")); + _exit(EXIT_FAILURE); + } + + if (close_stream(stderr) != 0) + _exit(EXIT_FAILURE); +} + +#endif /* UTIL_LINUX_CLOSESTREAM_H */ -- cgit v1.2.3-55-g7522