]>
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 | { | |
52aa1a66 | 42 | if (stdout && close_stream(stdout) != 0 && !(errno == EPIPE)) { |
302e423d SK |
43 | if (errno) |
44 | warn(_("write error")); | |
45 | else | |
46 | warnx(_("write error")); | |
090d8c76 | 47 | _exit(CLOSE_EXIT_CODE); |
302e423d SK |
48 | } |
49 | ||
52aa1a66 | 50 | if (stderr && close_stream(stderr) != 0) |
090d8c76 | 51 | _exit(CLOSE_EXIT_CODE); |
52aa1a66 KZ |
52 | |
53 | stdout = NULL; | |
54 | stderr = NULL; | |
302e423d SK |
55 | } |
56 | ||
31c66833 KZ |
57 | static inline void |
58 | close_stdout_atexit(void) | |
59 | { | |
60 | /* | |
61 | * Note that close stdout at exit disables ASAN to report memory leaks | |
62 | */ | |
084365f1 | 63 | #if !defined(__SANITIZE_ADDRESS__) |
31c66833 KZ |
64 | atexit(close_stdout); |
65 | #endif | |
66 | } | |
67 | ||
f416563b SK |
68 | #ifndef HAVE_FSYNC |
69 | static inline int | |
70 | fsync(int fd __attribute__((__unused__))) | |
71 | { | |
72 | return 0; | |
73 | } | |
74 | #endif | |
75 | ||
76 | static inline int | |
77 | close_fd(int fd) | |
78 | { | |
79 | const int fsync_fail = (fsync(fd) != 0); | |
80 | const int close_fail = (close(fd) != 0); | |
81 | ||
82 | if (fsync_fail || close_fail) | |
83 | return EOF; | |
84 | return 0; | |
85 | } | |
86 | ||
302e423d | 87 | #endif /* UTIL_LINUX_CLOSESTREAM_H */ |