]> git.ipfire.org Git - thirdparty/util-linux.git/blob - include/closestream.h
libfdisk: (dos) accept start for log.partitions on template
[thirdparty/util-linux.git] / include / closestream.h
1 #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 CLOSE_EXIT_CODE
14 # define CLOSE_EXIT_CODE EXIT_FAILURE
15 #endif
16
17 #ifndef HAVE___FPENDING
18 static inline int
19 __fpending(FILE *stream __attribute__((__unused__)))
20 {
21 return 0;
22 }
23 #endif
24
25 static inline int
26 close_stream(FILE * stream)
27 {
28 const int some_pending = (__fpending(stream) != 0);
29 const int prev_fail = (ferror(stream) != 0);
30 const int fclose_fail = (fclose(stream) != 0);
31
32 if (prev_fail || (fclose_fail && (some_pending || errno != EBADF))) {
33 if (!fclose_fail && !(errno == EPIPE))
34 errno = 0;
35 return EOF;
36 }
37 return 0;
38 }
39
40 /* Meant to be used atexit(close_stdout); */
41 static inline void
42 close_stdout(void)
43 {
44 if (close_stream(stdout) != 0 && !(errno == EPIPE)) {
45 if (errno)
46 warn(_("write error"));
47 else
48 warnx(_("write error"));
49 _exit(CLOSE_EXIT_CODE);
50 }
51
52 if (close_stream(stderr) != 0)
53 _exit(CLOSE_EXIT_CODE);
54 }
55
56 #ifndef HAVE_FSYNC
57 static inline int
58 fsync(int fd __attribute__((__unused__)))
59 {
60 return 0;
61 }
62 #endif
63
64 static inline int
65 close_fd(int fd)
66 {
67 const int fsync_fail = (fsync(fd) != 0);
68 const int close_fail = (close(fd) != 0);
69
70 if (fsync_fail || close_fail)
71 return EOF;
72 return 0;
73 }
74
75 #endif /* UTIL_LINUX_CLOSESTREAM_H */