From: Sami Kerola Date: Wed, 4 Apr 2012 17:22:08 +0000 (+0200) Subject: include: add stream error checking facility X-Git-Tag: v2.22-rc1~539^2~12 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=302e423dc1a6dd8f72e126ec3279a14938da625a;p=thirdparty%2Futil-linux.git 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 --- diff --git a/include/Makefile.am b/include/Makefile.am index b939f89fef..f6934ecfe0 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -7,6 +7,7 @@ dist_noinst_HEADERS = \ c.h \ canonicalize.h \ carefulputc.h \ + closestream.h \ cpuset.h \ crc32.h \ env.h \ diff --git a/include/closestream.h b/include/closestream.h new file mode 100644 index 0000000000..fb507eab8e --- /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 */