]>
git.ipfire.org Git - thirdparty/util-linux.git/blob - include/closestream.h
2 * No copyright is claimed. This code is in the public domain; do with
5 #ifndef UTIL_LINUX_CLOSESTREAM_H
6 #define UTIL_LINUX_CLOSESTREAM_H
9 #ifdef HAVE_STDIO_EXT_H
10 #include <stdio_ext.h>
17 #ifndef CLOSE_EXIT_CODE
18 # define CLOSE_EXIT_CODE EXIT_FAILURE
22 close_stream(FILE * stream
)
24 #ifdef HAVE___FPENDING
25 const int some_pending
= (__fpending(stream
) != 0);
27 const int prev_fail
= (ferror(stream
) != 0);
28 const int fclose_fail
= (fclose(stream
) != 0);
30 if (prev_fail
|| (fclose_fail
&& (
31 #ifdef HAVE___FPENDING
35 if (!fclose_fail
&& !(errno
== EPIPE
))
43 flush_standard_stream(FILE *stream
)
49 if (ferror(stream
) != 0 || fflush(stream
) != 0)
53 * Calling fflush is not sufficient on some filesystems
54 * like e.g. NFS, which may defer the actual flush until
55 * close. Calling fsync would help solve this, but would
56 * probably result in a performance hit. Thus, we work
57 * around this issue by calling close on a dup'd file
58 * descriptor from the stream.
60 if ((fd
= fileno(stream
)) < 0 || (fd
= dup(fd
)) < 0 || close(fd
) != 0)
65 return (errno
== EBADF
) ? 0 : EOF
;
68 /* Meant to be used atexit(close_stdout); */
72 if (flush_standard_stream(stdout
) != 0 && !(errno
== EPIPE
)) {
74 warn(_("write error"));
76 warnx(_("write error"));
77 _exit(CLOSE_EXIT_CODE
);
80 if (flush_standard_stream(stderr
) != 0)
81 _exit(CLOSE_EXIT_CODE
);
85 close_stdout_atexit(void)
88 * Note that close stdout at exit disables ASAN to report memory leaks
90 #if !HAS_FEATURE_ADDRESS_SANITIZER
97 fsync(int fd
__attribute__((__unused__
)))
106 const int fsync_fail
= (fsync(fd
) != 0);
107 const int close_fail
= (close(fd
) != 0);
109 if (fsync_fail
|| close_fail
)
114 #endif /* UTIL_LINUX_CLOSESTREAM_H */