]>
git.ipfire.org Git - thirdparty/util-linux.git/blob - include/closestream.h
1 #ifndef UTIL_LINUX_CLOSESTREAM_H
2 #define UTIL_LINUX_CLOSESTREAM_H
5 #ifdef HAVE_STDIO_EXT_H
13 #ifndef CLOSE_EXIT_CODE
14 # define CLOSE_EXIT_CODE EXIT_FAILURE
18 close_stream(FILE * stream
)
20 #ifdef HAVE___FPENDING
21 const int some_pending
= (__fpending(stream
) != 0);
23 const int prev_fail
= (ferror(stream
) != 0);
24 const int fclose_fail
= (fclose(stream
) != 0);
26 if (prev_fail
|| (fclose_fail
&& (
27 #ifdef HAVE___FPENDING
31 if (!fclose_fail
&& !(errno
== EPIPE
))
39 flush_standard_stream(FILE *stream
)
45 if (ferror(stream
) != 0 || fflush(stream
) != 0)
49 * Calling fflush is not sufficient on some filesystems
50 * like e.g. NFS, which may defer the actual flush until
51 * close. Calling fsync would help solve this, but would
52 * probably result in a performance hit. Thus, we work
53 * around this issue by calling close on a dup'd file
54 * descriptor from the stream.
56 if ((fd
= fileno(stream
)) < 0 || (fd
= dup(fd
)) < 0 || close(fd
) != 0)
61 return (errno
== EBADF
) ? 0 : EOF
;
64 /* Meant to be used atexit(close_stdout); */
68 if (flush_standard_stream(stdout
) != 0 && !(errno
== EPIPE
)) {
70 warn(_("write error"));
72 warnx(_("write error"));
73 _exit(CLOSE_EXIT_CODE
);
76 if (flush_standard_stream(stderr
) != 0)
77 _exit(CLOSE_EXIT_CODE
);
81 close_stdout_atexit(void)
84 * Note that close stdout at exit disables ASAN to report memory leaks
86 #if !defined(__SANITIZE_ADDRESS__)
93 fsync(int fd
__attribute__((__unused__
)))
102 const int fsync_fail
= (fsync(fd
) != 0);
103 const int close_fail
= (close(fd
) != 0);
105 if (fsync_fail
|| close_fail
)
110 #endif /* UTIL_LINUX_CLOSESTREAM_H */