diff options
author | Sami Kerola | 2012-04-04 19:22:08 +0200 |
---|---|---|
committer | Sami Kerola | 2012-04-04 19:45:37 +0200 |
commit | 302e423dc1a6dd8f72e126ec3279a14938da625a (patch) | |
tree | c6b9ab5a62148a1d6b205e3b7c797e7868b9dc2e /include/closestream.h | |
parent | lsblk: count with terminating character, man page -s entry (diff) | |
download | kernel-qcow2-util-linux-302e423dc1a6dd8f72e126ec3279a14938da625a.tar.gz kernel-qcow2-util-linux-302e423dc1a6dd8f72e126ec3279a14938da625a.tar.xz kernel-qcow2-util-linux-302e423dc1a6dd8f72e126ec3279a14938da625a.zip |
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 <kerolasa@iki.fi>
Diffstat (limited to 'include/closestream.h')
-rw-r--r-- | include/closestream.h | 41 |
1 files changed, 41 insertions, 0 deletions
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 <stdio.h> +#include <stdio_ext.h> +#include <unistd.h> + +#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 */ |