]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/ui-file.c
[gdb/testsuite] Fix gdb.base/break-probes.exp with native-gdbserver
[thirdparty/binutils-gdb.git] / gdb / ui-file.c
CommitLineData
d9fcf2fb 1/* UI_FILE - a generic STDIO like output stream.
349c5d5f 2
42a4f53d 3 Copyright (C) 1999-2019 Free Software Foundation, Inc.
d9fcf2fb
JM
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
a9762ec7 9 the Free Software Foundation; either version 3 of the License, or
d9fcf2fb
JM
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
a9762ec7 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
d9fcf2fb 19
581e13c1 20/* Implement the ``struct ui_file'' object. */
d9fcf2fb
JM
21
22#include "defs.h"
23#include "ui-file.h"
94af9270 24#include "gdb_obstack.h"
ad960ed2 25#include "gdb_select.h"
0747795c 26#include "common/filestuff.h"
d9fcf2fb 27
d7e74731 28null_file null_stream;
d9fcf2fb 29
d7e74731
PA
30ui_file::ui_file ()
31{}
d9fcf2fb 32
d7e74731
PA
33ui_file::~ui_file ()
34{}
d9fcf2fb 35
d7e74731
PA
36void
37ui_file::printf (const char *format, ...)
d9fcf2fb 38{
d7e74731 39 va_list args;
d9fcf2fb 40
d7e74731
PA
41 va_start (args, format);
42 vfprintf_unfiltered (this, format, args);
43 va_end (args);
d9fcf2fb
JM
44}
45
d7e74731
PA
46void
47ui_file::putstr (const char *str, int quoter)
d9fcf2fb 48{
d7e74731 49 fputstr_unfiltered (str, quoter, this);
d9fcf2fb
JM
50}
51
d7e74731
PA
52void
53ui_file::putstrn (const char *str, int n, int quoter)
d9fcf2fb 54{
7c4e78cf 55 fputstrn_unfiltered (str, n, quoter, fputc_unfiltered, this);
d9fcf2fb
JM
56}
57
d7e74731
PA
58int
59ui_file::putc (int c)
449092f6 60{
d7e74731 61 return fputc_unfiltered (c, this);
449092f6
CV
62}
63
d7e74731
PA
64void
65ui_file::vprintf (const char *format, va_list args)
d9fcf2fb 66{
d7e74731 67 vfprintf_unfiltered (this, format, args);
d9fcf2fb
JM
68}
69
d7e74731 70\f
01124a23 71
d7e74731
PA
72void
73null_file::write (const char *buf, long sizeof_buf)
d9fcf2fb 74{
d7e74731 75 /* Discard the request. */
d9fcf2fb
JM
76}
77
d7e74731
PA
78void
79null_file::puts (const char *)
2a9d5ccf 80{
d7e74731 81 /* Discard the request. */
2a9d5ccf
HZ
82}
83
d7e74731
PA
84void
85null_file::write_async_safe (const char *buf, long sizeof_buf)
d9fcf2fb 86{
d7e74731 87 /* Discard the request. */
d9fcf2fb
JM
88}
89
d7e74731
PA
90\f
91
d9fcf2fb 92void
fba45db2 93gdb_flush (struct ui_file *file)
d9fcf2fb 94{
d7e74731 95 file->flush ();
d9fcf2fb
JM
96}
97
98int
fba45db2 99ui_file_isatty (struct ui_file *file)
d9fcf2fb 100{
d7e74731 101 return file->isatty ();
d9fcf2fb
JM
102}
103
104void
105ui_file_write (struct ui_file *file,
106 const char *buf,
107 long length_buf)
108{
d7e74731 109 file->write (buf, length_buf);
de571fc5
TT
110}
111
01124a23
DE
112void
113ui_file_write_async_safe (struct ui_file *file,
114 const char *buf,
115 long length_buf)
116{
d7e74731 117 file->write_async_safe (buf, length_buf);
01124a23
DE
118}
119
449092f6
CV
120long
121ui_file_read (struct ui_file *file, char *buf, long length_buf)
122{
d7e74731 123 return file->read (buf, length_buf);
2a9d5ccf
HZ
124}
125
d9fcf2fb 126void
fba45db2 127fputs_unfiltered (const char *buf, struct ui_file *file)
d9fcf2fb 128{
d7e74731 129 file->puts (buf);
d9fcf2fb
JM
130}
131
d7e74731 132\f
d9fcf2fb 133
d7e74731
PA
134string_file::~string_file ()
135{}
d9fcf2fb
JM
136
137void
d7e74731 138string_file::write (const char *buf, long length_buf)
d9fcf2fb 139{
d7e74731 140 m_string.append (buf, length_buf);
d9fcf2fb
JM
141}
142
d7e74731 143\f
01124a23 144
d7e74731 145stdio_file::stdio_file (FILE *file, bool close_p)
449092f6 146{
d7e74731
PA
147 set_stream (file);
148 m_close_p = close_p;
449092f6
CV
149}
150
d7e74731
PA
151stdio_file::stdio_file ()
152 : m_file (NULL),
153 m_fd (-1),
154 m_close_p (false)
155{}
d9fcf2fb 156
d7e74731 157stdio_file::~stdio_file ()
2a9d5ccf 158{
d7e74731
PA
159 if (m_close_p)
160 fclose (m_file);
2a9d5ccf
HZ
161}
162
d9fcf2fb 163void
d7e74731 164stdio_file::set_stream (FILE *file)
d9fcf2fb 165{
d7e74731
PA
166 m_file = file;
167 m_fd = fileno (file);
d9fcf2fb
JM
168}
169
d7e74731
PA
170bool
171stdio_file::open (const char *name, const char *mode)
d9fcf2fb 172{
d7e74731
PA
173 /* Close the previous stream, if we own it. */
174 if (m_close_p)
175 {
176 fclose (m_file);
177 m_close_p = false;
178 }
5d502164 179
d419f42d 180 gdb_file_up f = gdb_fopen_cloexec (name, mode);
d9fcf2fb 181
d7e74731
PA
182 if (f == NULL)
183 return false;
d9fcf2fb 184
d419f42d 185 set_stream (f.release ());
d7e74731 186 m_close_p = true;
5d502164 187
d7e74731 188 return true;
d9fcf2fb
JM
189}
190
191void
d7e74731 192stdio_file::flush ()
d9fcf2fb 193{
d7e74731 194 fflush (m_file);
d9fcf2fb
JM
195}
196
d7e74731
PA
197long
198stdio_file::read (char *buf, long length_buf)
449092f6 199{
f0881b37
PA
200 /* Wait until at least one byte of data is available, or we get
201 interrupted with Control-C. */
ad960ed2 202 {
ad960ed2 203 fd_set readfds;
f0881b37 204
ad960ed2 205 FD_ZERO (&readfds);
d7e74731
PA
206 FD_SET (m_fd, &readfds);
207 if (interruptible_select (m_fd + 1, &readfds, NULL, NULL, NULL) == -1)
ad960ed2
DJ
208 return -1;
209 }
210
d7e74731 211 return ::read (m_fd, buf, length_buf);
449092f6
CV
212}
213
d7e74731
PA
214void
215stdio_file::write (const char *buf, long length_buf)
d9fcf2fb 216{
bf1d7d9c 217 /* Calling error crashes when we are called from the exception framework. */
d7e74731 218 if (fwrite (buf, length_buf, 1, m_file))
d4fb63e1
TT
219 {
220 /* Nothing. */
221 }
d9fcf2fb
JM
222}
223
d7e74731
PA
224void
225stdio_file::write_async_safe (const char *buf, long length_buf)
01124a23 226{
9f7bc587
DE
227 /* This is written the way it is to avoid a warning from gcc about not using the
228 result of write (since it can be declared with attribute warn_unused_result).
229 Alas casting to void doesn't work for this. */
d7e74731 230 if (::write (m_fd, buf, length_buf))
d4fb63e1
TT
231 {
232 /* Nothing. */
233 }
01124a23
DE
234}
235
d7e74731
PA
236void
237stdio_file::puts (const char *linebuffer)
d9fcf2fb 238{
e4adb939
EZ
239 /* This host-dependent function (with implementations in
240 posix-hdep.c and mingw-hdep.c) is given the opportunity to
241 process the output first in host-dependent way. If it does, it
242 should return non-zero, to avoid calling fputs below. */
243 if (gdb_console_fputs (linebuffer, m_file))
244 return;
bf1d7d9c 245 /* Calling error crashes when we are called from the exception framework. */
d7e74731 246 if (fputs (linebuffer, m_file))
d4fb63e1
TT
247 {
248 /* Nothing. */
249 }
d9fcf2fb
JM
250}
251
d7e74731
PA
252bool
253stdio_file::isatty ()
d9fcf2fb 254{
d7e74731 255 return ::isatty (m_fd);
d9fcf2fb
JM
256}
257
d7e74731 258\f
2a9d5ccf 259
d7e74731 260/* This is the implementation of ui_file method 'write' for stderr.
ffa4ac95
YQ
261 gdb_stdout is flushed before writing to gdb_stderr. */
262
d7e74731
PA
263void
264stderr_file::write (const char *buf, long length_buf)
ffa4ac95
YQ
265{
266 gdb_flush (gdb_stdout);
d7e74731 267 stdio_file::write (buf, length_buf);
ffa4ac95
YQ
268}
269
d7e74731 270/* This is the implementation of ui_file method 'puts' for stderr.
ffa4ac95
YQ
271 gdb_stdout is flushed before writing to gdb_stderr. */
272
d7e74731
PA
273void
274stderr_file::puts (const char *linebuffer)
ffa4ac95
YQ
275{
276 gdb_flush (gdb_stdout);
d7e74731 277 stdio_file::puts (linebuffer);
ffa4ac95 278}
ffa4ac95 279
d7e74731
PA
280stderr_file::stderr_file (FILE *stream)
281 : stdio_file (stream)
282{}
d9fcf2fb 283
d7e74731 284\f
e4c242d9 285
d7e74731
PA
286tee_file::tee_file (ui_file *one, bool close_one,
287 ui_file *two, bool close_two)
288 : m_one (one),
289 m_two (two),
290 m_close_one (close_one),
291 m_close_two (close_two)
292{}
e4c242d9 293
d7e74731 294tee_file::~tee_file ()
e4c242d9 295{
d7e74731
PA
296 if (m_close_one)
297 delete m_one;
298 if (m_close_two)
299 delete m_two;
e4c242d9
DJ
300}
301
d7e74731
PA
302void
303tee_file::flush ()
e4c242d9 304{
d7e74731
PA
305 m_one->flush ();
306 m_two->flush ();
e4c242d9
DJ
307}
308
d7e74731
PA
309void
310tee_file::write (const char *buf, long length_buf)
e4c242d9 311{
d7e74731
PA
312 m_one->write (buf, length_buf);
313 m_two->write (buf, length_buf);
e4c242d9
DJ
314}
315
d7e74731
PA
316void
317tee_file::write_async_safe (const char *buf, long length_buf)
e4c242d9 318{
d7e74731
PA
319 m_one->write_async_safe (buf, length_buf);
320 m_two->write_async_safe (buf, length_buf);
e4c242d9
DJ
321}
322
d7e74731
PA
323void
324tee_file::puts (const char *linebuffer)
e4c242d9 325{
d7e74731
PA
326 m_one->puts (linebuffer);
327 m_two->puts (linebuffer);
e4c242d9
DJ
328}
329
d7e74731
PA
330bool
331tee_file::isatty ()
e4c242d9 332{
d7e74731 333 return m_one->isatty ();
e4c242d9 334}