]>
Commit | Line | Data |
---|---|---|
302e423d SK |
1 | #ifndef UTIL_LINUX_CLOSESTREAM_H |
2 | #define UTIL_LINUX_CLOSESTREAM_H | |
3 | ||
4 | #include <stdio.h> | |
78288764 | 5 | #ifdef HAVE_STDIO_EXT_H |
302e423d | 6 | #include <stdio_ext.h> |
78288764 | 7 | #endif |
302e423d SK |
8 | #include <unistd.h> |
9 | ||
10 | #include "c.h" | |
11 | #include "nls.h" | |
12 | ||
090d8c76 KZ |
13 | #ifndef CLOSE_EXIT_CODE |
14 | # define CLOSE_EXIT_CODE EXIT_FAILURE | |
15 | #endif | |
16 | ||
302e423d SK |
17 | static inline int |
18 | close_stream(FILE * stream) | |
19 | { | |
b211467f | 20 | #ifdef HAVE___FPENDING |
302e423d | 21 | const int some_pending = (__fpending(stream) != 0); |
b211467f | 22 | #endif |
302e423d SK |
23 | const int prev_fail = (ferror(stream) != 0); |
24 | const int fclose_fail = (fclose(stream) != 0); | |
422f93bf | 25 | |
b211467f SK |
26 | if (prev_fail || (fclose_fail && ( |
27 | #ifdef HAVE___FPENDING | |
28 | some_pending || | |
29 | #endif | |
30 | errno != EBADF))) { | |
422f93bf | 31 | if (!fclose_fail && !(errno == EPIPE)) |
302e423d SK |
32 | errno = 0; |
33 | return EOF; | |
34 | } | |
35 | return 0; | |
36 | } | |
37 | ||
38 | /* Meant to be used atexit(close_stdout); */ | |
39 | static inline void | |
40 | close_stdout(void) | |
41 | { | |
42 | if (close_stream(stdout) != 0 && !(errno == EPIPE)) { | |
43 | if (errno) | |
44 | warn(_("write error")); | |
45 | else | |
46 | warnx(_("write error")); | |
090d8c76 | 47 | _exit(CLOSE_EXIT_CODE); |
302e423d SK |
48 | } |
49 | ||
50 | if (close_stream(stderr) != 0) | |
090d8c76 | 51 | _exit(CLOSE_EXIT_CODE); |
302e423d SK |
52 | } |
53 | ||
31c66833 KZ |
54 | static inline void |
55 | close_stdout_atexit(void) | |
56 | { | |
57 | /* | |
58 | * Note that close stdout at exit disables ASAN to report memory leaks | |
59 | */ | |
60 | #ifdef USE_CLOSE_ATEXIT | |
61 | atexit(close_stdout); | |
62 | #endif | |
63 | } | |
64 | ||
f416563b SK |
65 | #ifndef HAVE_FSYNC |
66 | static inline int | |
67 | fsync(int fd __attribute__((__unused__))) | |
68 | { | |
69 | return 0; | |
70 | } | |
71 | #endif | |
72 | ||
73 | static inline int | |
74 | close_fd(int fd) | |
75 | { | |
76 | const int fsync_fail = (fsync(fd) != 0); | |
77 | const int close_fail = (close(fd) != 0); | |
78 | ||
79 | if (fsync_fail || close_fail) | |
80 | return EOF; | |
81 | return 0; | |
82 | } | |
83 | ||
302e423d | 84 | #endif /* UTIL_LINUX_CLOSESTREAM_H */ |