blob: 7842456fbac0201d84896c45ccc078cf16409371 [file] [log] [blame]
bigbiff bigbiffe60683a2013-02-22 20:55:50 -05001#ifndef UTIL_LINUX_CLOSESTREAM_H
2#define UTIL_LINUX_CLOSESTREAM_H
3
4#include <stdio.h>
5#ifdef HAVE_STDIO_EXT_H
6#include <stdio_ext.h>
7#endif
8#include <unistd.h>
9
10#include "c.h"
11#include "nls.h"
12
13#ifndef HAVE___FPENDING
14static inline int
15__fpending(FILE *stream __attribute__((__unused__)))
16{
17 return 0;
18}
19#endif
20
21static inline int
22close_stream(FILE * stream)
23{
24 const int some_pending = (__fpending(stream) != 0);
25 const int prev_fail = (ferror(stream) != 0);
26 const int fclose_fail = (fclose(stream) != 0);
bigbiff7b4c7a62015-01-01 19:44:14 -050027
bigbiff bigbiffe60683a2013-02-22 20:55:50 -050028 if (prev_fail || (fclose_fail && (some_pending || errno != EBADF))) {
bigbiff7b4c7a62015-01-01 19:44:14 -050029 if (!fclose_fail && !(errno == EPIPE))
bigbiff bigbiffe60683a2013-02-22 20:55:50 -050030 errno = 0;
31 return EOF;
32 }
33 return 0;
34}
35
36/* Meant to be used atexit(close_stdout); */
37static inline void
38close_stdout(void)
39{
40 if (close_stream(stdout) != 0 && !(errno == EPIPE)) {
41 if (errno)
42 warn(_("write error"));
43 else
44 warnx(_("write error"));
45 _exit(EXIT_FAILURE);
46 }
47
48 if (close_stream(stderr) != 0)
49 _exit(EXIT_FAILURE);
50}
51
bigbiff7b4c7a62015-01-01 19:44:14 -050052#ifndef HAVE_FSYNC
53static inline int
54fsync(int fd __attribute__((__unused__)))
55{
56 return 0;
57}
58#endif
59
60static inline int
61close_fd(int fd)
62{
63 const int fsync_fail = (fsync(fd) != 0);
64 const int close_fail = (close(fd) != 0);
65
66 if (fsync_fail || close_fail)
67 return EOF;
68 return 0;
69}
70
bigbiff bigbiffe60683a2013-02-22 20:55:50 -050071#endif /* UTIL_LINUX_CLOSESTREAM_H */