diff options
Diffstat (limited to 'local/fileutils.c')
-rw-r--r-- | local/fileutils.c | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/local/fileutils.c b/local/fileutils.c new file mode 100644 index 0000000..14c7452 --- /dev/null +++ b/local/fileutils.c @@ -0,0 +1,45 @@ +#include <errno.h> +#ifdef HAVE_ERROR_H +# include <error.h> +#endif +#ifdef HAVE_STDIO_EXT_H +# include <stdio_ext.h> +#else +/* FIXME: use a more portable definition of __fpending() (from gnulib?) */ +# include <stdio.h> +# define __fpending(fp) ((fp)->_p - (fp)->_bf._base) +#endif +#include <stdlib.h> +#include <unistd.h> + +#include "nls.h" +#include "fileutils.h" +#ifndef HAVE_ERROR_H +# include "c.h" /* for error() emulation */ +#endif + +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 != EPIPE) + errno = 0; + return EOF; + } + return 0; +} + +/* Use atexit(); */ +void close_stdout(void) +{ + if (close_stream(stdout) != 0 && !(errno == EPIPE)) { + char const *write_error = _("write error"); + error(0, errno, "%s", write_error); + _exit(EXIT_FAILURE); + } + + if (close_stream(stderr) != 0) + _exit(EXIT_FAILURE); +} |