1 /* DO NOT EDIT! GENERATED AUTOMATICALLY! */
2
3 #if !IS_CPLUSPLUS
4 #define file_ostream_representation any_ostream_representation
5 #endif
6 #line 1 "file-ostream.oo.c"
7 /* Output stream referring to an stdio FILE.
8 Copyright (C) 2006, 2019-2020 Free Software Foundation, Inc.
9 Written by Bruno Haible <bruno@clisp.org>, 2006.
10
11 This program is free software: you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 3 of the License, or
14 (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program. If not, see <https://www.gnu.org/licenses/>. */
23
24 #include <config.h>
25
26 /* Specification. */
27 #include "file-ostream.h"
28
29 #include <errno.h>
30 #include <stdlib.h>
31 #include <unistd.h>
32 #if HAVE_TCDRAIN
33 # include <termios.h>
34 #endif
35
36 #include "xalloc.h"
37
38 #line 39 "file-ostream.c"
39 #include "file_ostream.priv.h"
40
41 const typeinfo_t file_ostream_typeinfo = { "file_ostream" };
42
43 static const typeinfo_t * const file_ostream_superclasses[] =
44 { file_ostream_SUPERCLASSES };
45
46 #define super ostream_vtable
47
48 #line 37 "file-ostream.oo.c"
49
50 #if HAVE_TCDRAIN
51
52 /* EINTR handling for tcdrain().
53 This function can return -1/EINTR even though we don't have any
54 signal handlers set up, namely when we get interrupted via SIGSTOP. */
55
56 static inline int
57 nonintr_tcdrain (int fd)
58 {
59 int retval;
60
61 do
62 retval = tcdrain (fd);
63 while (retval < 0 && errno == EINTR);
64
65 return retval;
66 }
67
68 #endif
69
70 /* Implementation of ostream_t methods. */
71
72 static void
73 file_ostream__write_mem (file_ostream_t stream, const void *data, size_t len)
74 {
75 if (len > 0)
76 fwrite (data, 1, len, stream->fp);
77 }
78
79 static void
80 file_ostream__flush (file_ostream_t stream, ostream_flush_scope_t scope)
81 {
82 /* This ostream has no internal buffer, therefore nothing to do for
83 scope == FLUSH_THIS_STREAM. */
84 if (scope != FLUSH_THIS_STREAM)
85 {
86 fflush (stream->fp);
87 if (scope == FLUSH_ALL)
88 {
89 int fd = fileno (stream->fp);
90 if (fd >= 0)
91 {
92 /* For streams connected to a disk file: */
93 fsync (fd);
94 #if HAVE_TCDRAIN
95 /* For streams connected to a terminal: */
96 nonintr_tcdrain (fd);
97 #endif
98 }
99 }
100 }
101 }
102
103 static void
104 file_ostream__free (file_ostream_t stream)
105 {
106 free (stream);
107 }
108
109 /* Constructor. */
110
111 file_ostream_t
112 file_ostream_create (FILE *fp)
113 {
114 file_ostream_t stream = XMALLOC (struct file_ostream_representation);
115
116 stream->base.vtable = &file_ostream_vtable;
117 stream->fp = fp;
118
119 return stream;
120 }
121
122 /* Accessors. */
123
124 static FILE *
125 file_ostream__get_stdio_stream (file_ostream_t stream)
126 {
127 return stream->fp;
128 }
129
130 /* Instanceof test. */
131
132 bool
133 is_instance_of_file_ostream (ostream_t stream)
134 {
135 return IS_INSTANCE (stream, ostream, file_ostream);
136 }
137
138 #line 139 "file-ostream.c"
139
140 const struct file_ostream_implementation file_ostream_vtable =
141 {
142 file_ostream_superclasses,
143 sizeof (file_ostream_superclasses) / sizeof (file_ostream_superclasses[0]),
144 sizeof (struct file_ostream_representation),
145 file_ostream__write_mem,
146 file_ostream__flush,
147 file_ostream__free,
148 file_ostream__get_stdio_stream,
149 };
150
151 #if !HAVE_INLINE
152
153 /* Define the functions that invoke the methods. */
154
155 void
156 file_ostream_write_mem (file_ostream_t first_arg, const void *data, size_t len)
157 {
158 const struct file_ostream_implementation *vtable =
159 ((struct file_ostream_representation_header *) (struct file_ostream_representation *) first_arg)->vtable;
160 vtable->write_mem (first_arg,data,len);
161 }
162
163 void
164 file_ostream_flush (file_ostream_t first_arg, ostream_flush_scope_t scope)
165 {
166 const struct file_ostream_implementation *vtable =
167 ((struct file_ostream_representation_header *) (struct file_ostream_representation *) first_arg)->vtable;
168 vtable->flush (first_arg,scope);
169 }
170
171 void
172 file_ostream_free (file_ostream_t first_arg)
173 {
174 const struct file_ostream_implementation *vtable =
175 ((struct file_ostream_representation_header *) (struct file_ostream_representation *) first_arg)->vtable;
176 vtable->free (first_arg);
177 }
178
179 FILE *
180 file_ostream_get_stdio_stream (file_ostream_t first_arg)
181 {
182 const struct file_ostream_implementation *vtable =
183 ((struct file_ostream_representation_header *) (struct file_ostream_representation *) first_arg)->vtable;
184 return vtable->get_stdio_stream (first_arg);
185 }
186
187 #endif