]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/ui-file.c
Make out and error streams be per UI
[thirdparty/binutils-gdb.git] / gdb / ui-file.c
CommitLineData
d9fcf2fb 1/* UI_FILE - a generic STDIO like output stream.
349c5d5f 2
618f726f 3 Copyright (C) 1999-2016 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"
614c279d 26#include "filestuff.h"
d9fcf2fb 27
d9fcf2fb
JM
28static ui_file_isatty_ftype null_file_isatty;
29static ui_file_write_ftype null_file_write;
01124a23 30static ui_file_write_ftype null_file_write_async_safe;
d9fcf2fb 31static ui_file_fputs_ftype null_file_fputs;
449092f6 32static ui_file_read_ftype null_file_read;
d9fcf2fb
JM
33static ui_file_flush_ftype null_file_flush;
34static ui_file_delete_ftype null_file_delete;
35static ui_file_rewind_ftype null_file_rewind;
36static ui_file_put_ftype null_file_put;
2a9d5ccf 37static ui_file_fseek_ftype null_file_fseek;
d9fcf2fb
JM
38
39struct ui_file
40 {
41 int *magic;
42 ui_file_flush_ftype *to_flush;
43 ui_file_write_ftype *to_write;
01124a23 44 ui_file_write_async_safe_ftype *to_write_async_safe;
d9fcf2fb 45 ui_file_fputs_ftype *to_fputs;
449092f6 46 ui_file_read_ftype *to_read;
d9fcf2fb
JM
47 ui_file_delete_ftype *to_delete;
48 ui_file_isatty_ftype *to_isatty;
49 ui_file_rewind_ftype *to_rewind;
50 ui_file_put_ftype *to_put;
2a9d5ccf 51 ui_file_fseek_ftype *to_fseek;
d9fcf2fb
JM
52 void *to_data;
53 };
54int ui_file_magic;
55
56struct ui_file *
fba45db2 57ui_file_new (void)
d9fcf2fb 58{
8d749320 59 struct ui_file *file = XNEW (struct ui_file);
5d502164 60
d9fcf2fb
JM
61 file->magic = &ui_file_magic;
62 set_ui_file_data (file, NULL, null_file_delete);
63 set_ui_file_flush (file, null_file_flush);
64 set_ui_file_write (file, null_file_write);
01124a23 65 set_ui_file_write_async_safe (file, null_file_write_async_safe);
d9fcf2fb 66 set_ui_file_fputs (file, null_file_fputs);
449092f6 67 set_ui_file_read (file, null_file_read);
d9fcf2fb
JM
68 set_ui_file_isatty (file, null_file_isatty);
69 set_ui_file_rewind (file, null_file_rewind);
70 set_ui_file_put (file, null_file_put);
2a9d5ccf 71 set_ui_file_fseek (file, null_file_fseek);
d9fcf2fb
JM
72 return file;
73}
74
75void
fba45db2 76ui_file_delete (struct ui_file *file)
d9fcf2fb
JM
77{
78 file->to_delete (file);
b8c9b27d 79 xfree (file);
d9fcf2fb
JM
80}
81
82static int
fba45db2 83null_file_isatty (struct ui_file *file)
d9fcf2fb
JM
84{
85 return 0;
86}
87
88static void
fba45db2 89null_file_rewind (struct ui_file *file)
d9fcf2fb
JM
90{
91 return;
92}
93
94static void
95null_file_put (struct ui_file *file,
96 ui_file_put_method_ftype *write,
97 void *dest)
98{
99 return;
100}
101
102static void
fba45db2 103null_file_flush (struct ui_file *file)
d9fcf2fb
JM
104{
105 return;
106}
107
108static void
109null_file_write (struct ui_file *file,
110 const char *buf,
111 long sizeof_buf)
112{
113 if (file->to_fputs == null_file_fputs)
581e13c1
MS
114 /* Both the write and fputs methods are null. Discard the
115 request. */
d9fcf2fb
JM
116 return;
117 else
118 {
119 /* The fputs method isn't null, slowly pass the write request
120 onto that. FYI, this isn't as bad as it may look - the
121 current (as of 1999-11-07) printf_* function calls fputc and
122 fputc does exactly the below. By having a write function it
123 is possible to clean up that code. */
124 int i;
125 char b[2];
5d502164 126
d9fcf2fb
JM
127 b[1] = '\0';
128 for (i = 0; i < sizeof_buf; i++)
129 {
130 b[0] = buf[i];
131 file->to_fputs (b, file);
132 }
133 return;
134 }
135}
136
449092f6
CV
137static long
138null_file_read (struct ui_file *file,
139 char *buf,
140 long sizeof_buf)
141{
142 errno = EBADF;
143 return 0;
144}
145
d9fcf2fb 146static void
fba45db2 147null_file_fputs (const char *buf, struct ui_file *file)
d9fcf2fb
JM
148{
149 if (file->to_write == null_file_write)
581e13c1
MS
150 /* Both the write and fputs methods are null. Discard the
151 request. */
d9fcf2fb
JM
152 return;
153 else
154 {
581e13c1 155 /* The write method was implemented, use that. */
d9fcf2fb
JM
156 file->to_write (file, buf, strlen (buf));
157 }
158}
159
01124a23
DE
160static void
161null_file_write_async_safe (struct ui_file *file,
162 const char *buf,
163 long sizeof_buf)
164{
165 return;
166}
167
d9fcf2fb 168static void
fba45db2 169null_file_delete (struct ui_file *file)
d9fcf2fb
JM
170{
171 return;
172}
173
2a9d5ccf
HZ
174static int
175null_file_fseek (struct ui_file *stream, long offset, int whence)
176{
177 errno = EBADF;
178
179 return -1;
180}
181
d9fcf2fb 182void *
fba45db2 183ui_file_data (struct ui_file *file)
d9fcf2fb
JM
184{
185 if (file->magic != &ui_file_magic)
8e65ff28 186 internal_error (__FILE__, __LINE__,
e2e0b3e5 187 _("ui_file_data: bad magic number"));
d9fcf2fb
JM
188 return file->to_data;
189}
190
191void
fba45db2 192gdb_flush (struct ui_file *file)
d9fcf2fb
JM
193{
194 file->to_flush (file);
195}
196
197int
fba45db2 198ui_file_isatty (struct ui_file *file)
d9fcf2fb
JM
199{
200 return file->to_isatty (file);
201}
202
203void
fba45db2 204ui_file_rewind (struct ui_file *file)
d9fcf2fb
JM
205{
206 file->to_rewind (file);
207}
208
209void
210ui_file_put (struct ui_file *file,
211 ui_file_put_method_ftype *write,
212 void *dest)
213{
214 file->to_put (file, write, dest);
215}
216
217void
218ui_file_write (struct ui_file *file,
219 const char *buf,
220 long length_buf)
221{
222 file->to_write (file, buf, length_buf);
223}
224
de571fc5
TT
225void
226ui_file_write_for_put (void *data, const char *buffer, long length_buffer)
227{
19ba03f4 228 ui_file_write ((struct ui_file *) data, buffer, length_buffer);
de571fc5
TT
229}
230
01124a23
DE
231void
232ui_file_write_async_safe (struct ui_file *file,
233 const char *buf,
234 long length_buf)
235{
236 file->to_write_async_safe (file, buf, length_buf);
237}
238
449092f6
CV
239long
240ui_file_read (struct ui_file *file, char *buf, long length_buf)
241{
242 return file->to_read (file, buf, length_buf);
243}
244
2a9d5ccf
HZ
245int
246ui_file_fseek (struct ui_file *file, long offset, int whence)
247{
248 return file->to_fseek (file, offset, whence);
249}
250
d9fcf2fb 251void
fba45db2 252fputs_unfiltered (const char *buf, struct ui_file *file)
d9fcf2fb
JM
253{
254 file->to_fputs (buf, file);
255}
256
257void
3f453875 258set_ui_file_flush (struct ui_file *file, ui_file_flush_ftype *flush_ptr)
d9fcf2fb 259{
3f453875 260 file->to_flush = flush_ptr;
d9fcf2fb
JM
261}
262
263void
3f453875 264set_ui_file_isatty (struct ui_file *file, ui_file_isatty_ftype *isatty_ptr)
d9fcf2fb 265{
3f453875 266 file->to_isatty = isatty_ptr;
d9fcf2fb
JM
267}
268
269void
3f453875 270set_ui_file_rewind (struct ui_file *file, ui_file_rewind_ftype *rewind_ptr)
d9fcf2fb 271{
3f453875 272 file->to_rewind = rewind_ptr;
d9fcf2fb
JM
273}
274
275void
3f453875 276set_ui_file_put (struct ui_file *file, ui_file_put_ftype *put_ptr)
d9fcf2fb 277{
3f453875 278 file->to_put = put_ptr;
d9fcf2fb
JM
279}
280
281void
282set_ui_file_write (struct ui_file *file,
3f453875 283 ui_file_write_ftype *write_ptr)
d9fcf2fb 284{
3f453875 285 file->to_write = write_ptr;
d9fcf2fb
JM
286}
287
01124a23
DE
288void
289set_ui_file_write_async_safe (struct ui_file *file,
3f453875 290 ui_file_write_async_safe_ftype *write_async_safe_ptr)
01124a23 291{
3f453875 292 file->to_write_async_safe = write_async_safe_ptr;
01124a23
DE
293}
294
449092f6 295void
3f453875 296set_ui_file_read (struct ui_file *file, ui_file_read_ftype *read_ptr)
449092f6 297{
3f453875 298 file->to_read = read_ptr;
449092f6
CV
299}
300
d9fcf2fb 301void
3f453875 302set_ui_file_fputs (struct ui_file *file, ui_file_fputs_ftype *fputs_ptr)
d9fcf2fb 303{
3f453875 304 file->to_fputs = fputs_ptr;
d9fcf2fb
JM
305}
306
2a9d5ccf
HZ
307void
308set_ui_file_fseek (struct ui_file *file, ui_file_fseek_ftype *fseek_ptr)
309{
310 file->to_fseek = fseek_ptr;
311}
312
d9fcf2fb 313void
fba45db2 314set_ui_file_data (struct ui_file *file, void *data,
3f453875 315 ui_file_delete_ftype *delete_ptr)
d9fcf2fb
JM
316{
317 file->to_data = data;
3f453875 318 file->to_delete = delete_ptr;
d9fcf2fb
JM
319}
320
321/* ui_file utility function for converting a ``struct ui_file'' into
581e13c1 322 a memory buffer. */
d9fcf2fb
JM
323
324struct accumulated_ui_file
325{
326 char *buffer;
327 long length;
328};
329
330static void
331do_ui_file_xstrdup (void *context, const char *buffer, long length)
332{
19ba03f4 333 struct accumulated_ui_file *acc = (struct accumulated_ui_file *) context;
5d502164 334
d9fcf2fb 335 if (acc->buffer == NULL)
224c3ddb 336 acc->buffer = (char *) xmalloc (length + 1);
d9fcf2fb 337 else
224c3ddb 338 acc->buffer = (char *) xrealloc (acc->buffer, acc->length + length + 1);
d9fcf2fb
JM
339 memcpy (acc->buffer + acc->length, buffer, length);
340 acc->length += length;
341 acc->buffer[acc->length] = '\0';
342}
343
344char *
759ef836 345ui_file_xstrdup (struct ui_file *file, long *length)
d9fcf2fb
JM
346{
347 struct accumulated_ui_file acc;
5d502164 348
d9fcf2fb
JM
349 acc.buffer = NULL;
350 acc.length = 0;
351 ui_file_put (file, do_ui_file_xstrdup, &acc);
352 if (acc.buffer == NULL)
353 acc.buffer = xstrdup ("");
759ef836
PA
354 if (length != NULL)
355 *length = acc.length;
d9fcf2fb
JM
356 return acc.buffer;
357}
94af9270
KS
358
359static void
360do_ui_file_obsavestring (void *context, const char *buffer, long length)
361{
362 struct obstack *obstack = (struct obstack *) context;
5d502164 363
94af9270
KS
364 obstack_grow (obstack, buffer, length);
365}
366
367char *
368ui_file_obsavestring (struct ui_file *file, struct obstack *obstack,
369 long *length)
370{
371 ui_file_put (file, do_ui_file_obsavestring, obstack);
372 *length = obstack_object_size (obstack);
373 obstack_1grow (obstack, '\0');
224c3ddb 374 return (char *) obstack_finish (obstack);
94af9270 375}
d9fcf2fb
JM
376\f
377/* A pure memory based ``struct ui_file'' that can be used an output
581e13c1
MS
378 buffer. The buffers accumulated contents are available via
379 ui_file_put(). */
d9fcf2fb
JM
380
381struct mem_file
382 {
383 int *magic;
384 char *buffer;
385 int sizeof_buffer;
386 int length_buffer;
387 };
388
389static ui_file_rewind_ftype mem_file_rewind;
390static ui_file_put_ftype mem_file_put;
391static ui_file_write_ftype mem_file_write;
392static ui_file_delete_ftype mem_file_delete;
a14ed312 393static struct ui_file *mem_file_new (void);
d9fcf2fb
JM
394static int mem_file_magic;
395
396static struct ui_file *
397mem_file_new (void)
398{
70ba0933 399 struct mem_file *stream = XNEW (struct mem_file);
d9fcf2fb 400 struct ui_file *file = ui_file_new ();
5d502164 401
d9fcf2fb
JM
402 set_ui_file_data (file, stream, mem_file_delete);
403 set_ui_file_rewind (file, mem_file_rewind);
404 set_ui_file_put (file, mem_file_put);
405 set_ui_file_write (file, mem_file_write);
406 stream->magic = &mem_file_magic;
407 stream->buffer = NULL;
408 stream->sizeof_buffer = 0;
409 stream->length_buffer = 0;
410 return file;
411}
412
413static void
414mem_file_delete (struct ui_file *file)
415{
19ba03f4 416 struct mem_file *stream = (struct mem_file *) ui_file_data (file);
5d502164 417
d9fcf2fb 418 if (stream->magic != &mem_file_magic)
8e65ff28 419 internal_error (__FILE__, __LINE__,
e2e0b3e5 420 _("mem_file_delete: bad magic number"));
d9fcf2fb 421 if (stream->buffer != NULL)
b8c9b27d
KB
422 xfree (stream->buffer);
423 xfree (stream);
d9fcf2fb
JM
424}
425
426struct ui_file *
427mem_fileopen (void)
428{
429 return mem_file_new ();
430}
431
432static void
433mem_file_rewind (struct ui_file *file)
434{
19ba03f4 435 struct mem_file *stream = (struct mem_file *) ui_file_data (file);
5d502164 436
d9fcf2fb 437 if (stream->magic != &mem_file_magic)
8e65ff28 438 internal_error (__FILE__, __LINE__,
e2e0b3e5 439 _("mem_file_rewind: bad magic number"));
d9fcf2fb
JM
440 stream->length_buffer = 0;
441}
442
443static void
444mem_file_put (struct ui_file *file,
445 ui_file_put_method_ftype *write,
446 void *dest)
447{
19ba03f4 448 struct mem_file *stream = (struct mem_file *) ui_file_data (file);
5d502164 449
d9fcf2fb 450 if (stream->magic != &mem_file_magic)
8e65ff28 451 internal_error (__FILE__, __LINE__,
e2e0b3e5 452 _("mem_file_put: bad magic number"));
d9fcf2fb
JM
453 if (stream->length_buffer > 0)
454 write (dest, stream->buffer, stream->length_buffer);
455}
456
457void
458mem_file_write (struct ui_file *file,
459 const char *buffer,
460 long length_buffer)
461{
19ba03f4 462 struct mem_file *stream = (struct mem_file *) ui_file_data (file);
5d502164 463
d9fcf2fb 464 if (stream->magic != &mem_file_magic)
8e65ff28 465 internal_error (__FILE__, __LINE__,
e2e0b3e5 466 _("mem_file_write: bad magic number"));
d9fcf2fb
JM
467 if (stream->buffer == NULL)
468 {
469 stream->length_buffer = length_buffer;
470 stream->sizeof_buffer = length_buffer;
224c3ddb 471 stream->buffer = (char *) xmalloc (stream->sizeof_buffer);
d9fcf2fb
JM
472 memcpy (stream->buffer, buffer, length_buffer);
473 }
474 else
475 {
476 int new_length = stream->length_buffer + length_buffer;
5d502164 477
d9fcf2fb
JM
478 if (new_length >= stream->sizeof_buffer)
479 {
480 stream->sizeof_buffer = new_length;
224c3ddb
SM
481 stream->buffer
482 = (char *) xrealloc (stream->buffer, stream->sizeof_buffer);
d9fcf2fb
JM
483 }
484 memcpy (stream->buffer + stream->length_buffer, buffer, length_buffer);
485 stream->length_buffer = new_length;
486 }
487}
488\f
489/* ``struct ui_file'' implementation that maps directly onto
581e13c1 490 <stdio.h>'s FILE. */
d9fcf2fb
JM
491
492static ui_file_write_ftype stdio_file_write;
01124a23 493static ui_file_write_async_safe_ftype stdio_file_write_async_safe;
d9fcf2fb 494static ui_file_fputs_ftype stdio_file_fputs;
449092f6 495static ui_file_read_ftype stdio_file_read;
d9fcf2fb
JM
496static ui_file_isatty_ftype stdio_file_isatty;
497static ui_file_delete_ftype stdio_file_delete;
3e43a32a 498static struct ui_file *stdio_file_new (FILE *file, int close_p);
d9fcf2fb 499static ui_file_flush_ftype stdio_file_flush;
2a9d5ccf 500static ui_file_fseek_ftype stdio_file_fseek;
d9fcf2fb
JM
501
502static int stdio_file_magic;
503
504struct stdio_file
505 {
506 int *magic;
507 FILE *file;
01124a23
DE
508 /* The associated file descriptor is extracted ahead of time for
509 stdio_file_write_async_safe's benefit, in case fileno isn't async-safe. */
510 int fd;
d9fcf2fb
JM
511 int close_p;
512 };
513
514static struct ui_file *
fba45db2 515stdio_file_new (FILE *file, int close_p)
d9fcf2fb
JM
516{
517 struct ui_file *ui_file = ui_file_new ();
8d749320 518 struct stdio_file *stdio = XNEW (struct stdio_file);
5d502164 519
d9fcf2fb
JM
520 stdio->magic = &stdio_file_magic;
521 stdio->file = file;
01124a23 522 stdio->fd = fileno (file);
d9fcf2fb
JM
523 stdio->close_p = close_p;
524 set_ui_file_data (ui_file, stdio, stdio_file_delete);
525 set_ui_file_flush (ui_file, stdio_file_flush);
526 set_ui_file_write (ui_file, stdio_file_write);
01124a23 527 set_ui_file_write_async_safe (ui_file, stdio_file_write_async_safe);
d9fcf2fb 528 set_ui_file_fputs (ui_file, stdio_file_fputs);
449092f6 529 set_ui_file_read (ui_file, stdio_file_read);
d9fcf2fb 530 set_ui_file_isatty (ui_file, stdio_file_isatty);
2a9d5ccf 531 set_ui_file_fseek (ui_file, stdio_file_fseek);
d9fcf2fb
JM
532 return ui_file;
533}
534
535static void
fba45db2 536stdio_file_delete (struct ui_file *file)
d9fcf2fb 537{
19ba03f4 538 struct stdio_file *stdio = (struct stdio_file *) ui_file_data (file);
5d502164 539
d9fcf2fb 540 if (stdio->magic != &stdio_file_magic)
8e65ff28 541 internal_error (__FILE__, __LINE__,
e2e0b3e5 542 _("stdio_file_delete: bad magic number"));
d9fcf2fb
JM
543 if (stdio->close_p)
544 {
545 fclose (stdio->file);
546 }
b8c9b27d 547 xfree (stdio);
d9fcf2fb
JM
548}
549
550static void
fba45db2 551stdio_file_flush (struct ui_file *file)
d9fcf2fb 552{
19ba03f4 553 struct stdio_file *stdio = (struct stdio_file *) ui_file_data (file);
5d502164 554
d9fcf2fb 555 if (stdio->magic != &stdio_file_magic)
8e65ff28 556 internal_error (__FILE__, __LINE__,
e2e0b3e5 557 _("stdio_file_flush: bad magic number"));
d9fcf2fb
JM
558 fflush (stdio->file);
559}
560
449092f6
CV
561static long
562stdio_file_read (struct ui_file *file, char *buf, long length_buf)
563{
19ba03f4 564 struct stdio_file *stdio = (struct stdio_file *) ui_file_data (file);
5d502164 565
449092f6
CV
566 if (stdio->magic != &stdio_file_magic)
567 internal_error (__FILE__, __LINE__,
e2e0b3e5 568 _("stdio_file_read: bad magic number"));
ad960ed2 569
f0881b37
PA
570 /* Wait until at least one byte of data is available, or we get
571 interrupted with Control-C. */
ad960ed2 572 {
ad960ed2 573 fd_set readfds;
f0881b37 574
ad960ed2 575 FD_ZERO (&readfds);
01124a23 576 FD_SET (stdio->fd, &readfds);
f0881b37 577 if (interruptible_select (stdio->fd + 1, &readfds, NULL, NULL, NULL) == -1)
ad960ed2
DJ
578 return -1;
579 }
580
01124a23 581 return read (stdio->fd, buf, length_buf);
449092f6
CV
582}
583
d9fcf2fb
JM
584static void
585stdio_file_write (struct ui_file *file, const char *buf, long length_buf)
586{
19ba03f4 587 struct stdio_file *stdio = (struct stdio_file *) ui_file_data (file);
5d502164 588
d9fcf2fb 589 if (stdio->magic != &stdio_file_magic)
8e65ff28 590 internal_error (__FILE__, __LINE__,
e2e0b3e5 591 _("stdio_file_write: bad magic number"));
bf1d7d9c
JB
592 /* Calling error crashes when we are called from the exception framework. */
593 if (fwrite (buf, length_buf, 1, stdio->file))
d4fb63e1
TT
594 {
595 /* Nothing. */
596 }
d9fcf2fb
JM
597}
598
01124a23
DE
599static void
600stdio_file_write_async_safe (struct ui_file *file,
601 const char *buf, long length_buf)
602{
19ba03f4 603 struct stdio_file *stdio = (struct stdio_file *) ui_file_data (file);
01124a23
DE
604
605 if (stdio->magic != &stdio_file_magic)
606 {
607 /* gettext isn't necessarily async safe, so we can't use _("error message") here.
608 We could extract the correct translation ahead of time, but this is an extremely
609 rare event, and one of the other stdio_file_* routines will presumably catch
610 the problem anyway. For now keep it simple and ignore the error here. */
611 return;
612 }
613
9f7bc587
DE
614 /* This is written the way it is to avoid a warning from gcc about not using the
615 result of write (since it can be declared with attribute warn_unused_result).
616 Alas casting to void doesn't work for this. */
093cee7d 617 if (write (stdio->fd, buf, length_buf))
d4fb63e1
TT
618 {
619 /* Nothing. */
620 }
01124a23
DE
621}
622
d9fcf2fb 623static void
fba45db2 624stdio_file_fputs (const char *linebuffer, struct ui_file *file)
d9fcf2fb 625{
19ba03f4 626 struct stdio_file *stdio = (struct stdio_file *) ui_file_data (file);
5d502164 627
d9fcf2fb 628 if (stdio->magic != &stdio_file_magic)
8e65ff28 629 internal_error (__FILE__, __LINE__,
e2e0b3e5 630 _("stdio_file_fputs: bad magic number"));
bf1d7d9c
JB
631 /* Calling error crashes when we are called from the exception framework. */
632 if (fputs (linebuffer, stdio->file))
d4fb63e1
TT
633 {
634 /* Nothing. */
635 }
d9fcf2fb
JM
636}
637
638static int
fba45db2 639stdio_file_isatty (struct ui_file *file)
d9fcf2fb 640{
19ba03f4 641 struct stdio_file *stdio = (struct stdio_file *) ui_file_data (file);
5d502164 642
d9fcf2fb 643 if (stdio->magic != &stdio_file_magic)
8e65ff28 644 internal_error (__FILE__, __LINE__,
e2e0b3e5 645 _("stdio_file_isatty: bad magic number"));
01124a23 646 return (isatty (stdio->fd));
d9fcf2fb
JM
647}
648
2a9d5ccf
HZ
649static int
650stdio_file_fseek (struct ui_file *file, long offset, int whence)
651{
19ba03f4 652 struct stdio_file *stdio = (struct stdio_file *) ui_file_data (file);
2a9d5ccf
HZ
653
654 if (stdio->magic != &stdio_file_magic)
655 internal_error (__FILE__, __LINE__,
656 _("stdio_file_fseek: bad magic number"));
657
658 return fseek (stdio->file, offset, whence);
659}
660
ffa4ac95
YQ
661#ifdef __MINGW32__
662/* This is the implementation of ui_file method to_write for stderr.
663 gdb_stdout is flushed before writing to gdb_stderr. */
664
665static void
666stderr_file_write (struct ui_file *file, const char *buf, long length_buf)
667{
668 gdb_flush (gdb_stdout);
669 stdio_file_write (file, buf, length_buf);
670}
671
672/* This is the implementation of ui_file method to_fputs for stderr.
673 gdb_stdout is flushed before writing to gdb_stderr. */
674
675static void
676stderr_file_fputs (const char *linebuffer, struct ui_file *file)
677{
678 gdb_flush (gdb_stdout);
679 stdio_file_fputs (linebuffer, file);
680}
681#endif
682
683struct ui_file *
694ec099 684stderr_fileopen (FILE *stream)
ffa4ac95 685{
694ec099 686 struct ui_file *ui_file = stdio_fileopen (stream);
ffa4ac95
YQ
687
688#ifdef __MINGW32__
689 /* There is no real line-buffering on Windows, see
690 http://msdn.microsoft.com/en-us/library/86cebhfs%28v=vs.71%29.aspx
691 so the stdout is either fully-buffered or non-buffered. We can't
692 make stdout non-buffered, because of two concerns,
693 1. non-buffering hurts performance,
694 2. non-buffering may change GDB's behavior when it is interacting
695 with front-end, such as Emacs.
696
697 We decided to leave stdout as fully buffered, but flush it first
698 when something is written to stderr. */
699
700 /* Method 'to_write_async_safe' is not overwritten, because there's
701 no way to flush a stream in an async-safe manner. Fortunately,
702 it doesn't really matter, because:
703 - that method is only used for printing internal debug output
704 from signal handlers.
705 - Windows hosts don't have a concept of async-safeness. Signal
706 handlers run in a separate thread, so they can call
707 the regular non-async-safe output routines freely. */
708 set_ui_file_write (ui_file, stderr_file_write);
709 set_ui_file_fputs (ui_file, stderr_file_fputs);
710#endif
711
712 return ui_file;
713}
714
581e13c1 715/* Like fdopen(). Create a ui_file from a previously opened FILE. */
d9fcf2fb
JM
716
717struct ui_file *
fba45db2 718stdio_fileopen (FILE *file)
d9fcf2fb
JM
719{
720 return stdio_file_new (file, 0);
721}
722
723struct ui_file *
23b3a2c3 724gdb_fopen (const char *name, const char *mode)
d9fcf2fb 725{
614c279d 726 FILE *f = gdb_fopen_cloexec (name, mode);
5d502164 727
d9fcf2fb
JM
728 if (f == NULL)
729 return NULL;
730 return stdio_file_new (f, 1);
731}
e4c242d9
DJ
732
733/* ``struct ui_file'' implementation that maps onto two ui-file objects. */
734
735static ui_file_write_ftype tee_file_write;
736static ui_file_fputs_ftype tee_file_fputs;
737static ui_file_isatty_ftype tee_file_isatty;
738static ui_file_delete_ftype tee_file_delete;
739static ui_file_flush_ftype tee_file_flush;
740
741static int tee_file_magic;
742
743struct tee_file
744 {
745 int *magic;
746 struct ui_file *one, *two;
747 int close_one, close_two;
748 };
749
750struct ui_file *
751tee_file_new (struct ui_file *one, int close_one,
752 struct ui_file *two, int close_two)
753{
754 struct ui_file *ui_file = ui_file_new ();
8d749320 755 struct tee_file *tee = XNEW (struct tee_file);
5d502164 756
e4c242d9
DJ
757 tee->magic = &tee_file_magic;
758 tee->one = one;
759 tee->two = two;
760 tee->close_one = close_one;
761 tee->close_two = close_two;
762 set_ui_file_data (ui_file, tee, tee_file_delete);
763 set_ui_file_flush (ui_file, tee_file_flush);
764 set_ui_file_write (ui_file, tee_file_write);
765 set_ui_file_fputs (ui_file, tee_file_fputs);
766 set_ui_file_isatty (ui_file, tee_file_isatty);
767 return ui_file;
768}
769
770static void
771tee_file_delete (struct ui_file *file)
772{
19ba03f4 773 struct tee_file *tee = (struct tee_file *) ui_file_data (file);
5d502164 774
e4c242d9
DJ
775 if (tee->magic != &tee_file_magic)
776 internal_error (__FILE__, __LINE__,
e2e0b3e5 777 _("tee_file_delete: bad magic number"));
e4c242d9
DJ
778 if (tee->close_one)
779 ui_file_delete (tee->one);
780 if (tee->close_two)
781 ui_file_delete (tee->two);
782
783 xfree (tee);
784}
785
786static void
787tee_file_flush (struct ui_file *file)
788{
19ba03f4 789 struct tee_file *tee = (struct tee_file *) ui_file_data (file);
5d502164 790
e4c242d9
DJ
791 if (tee->magic != &tee_file_magic)
792 internal_error (__FILE__, __LINE__,
e2e0b3e5 793 _("tee_file_flush: bad magic number"));
e4c242d9
DJ
794 tee->one->to_flush (tee->one);
795 tee->two->to_flush (tee->two);
796}
797
798static void
799tee_file_write (struct ui_file *file, const char *buf, long length_buf)
800{
19ba03f4 801 struct tee_file *tee = (struct tee_file *) ui_file_data (file);
5d502164 802
e4c242d9
DJ
803 if (tee->magic != &tee_file_magic)
804 internal_error (__FILE__, __LINE__,
e2e0b3e5 805 _("tee_file_write: bad magic number"));
e4c242d9
DJ
806 ui_file_write (tee->one, buf, length_buf);
807 ui_file_write (tee->two, buf, length_buf);
808}
809
810static void
811tee_file_fputs (const char *linebuffer, struct ui_file *file)
812{
19ba03f4 813 struct tee_file *tee = (struct tee_file *) ui_file_data (file);
5d502164 814
e4c242d9
DJ
815 if (tee->magic != &tee_file_magic)
816 internal_error (__FILE__, __LINE__,
e2e0b3e5 817 _("tee_file_fputs: bad magic number"));
e4c242d9
DJ
818 tee->one->to_fputs (linebuffer, tee->one);
819 tee->two->to_fputs (linebuffer, tee->two);
820}
821
822static int
823tee_file_isatty (struct ui_file *file)
824{
19ba03f4 825 struct tee_file *tee = (struct tee_file *) ui_file_data (file);
5d502164 826
e4c242d9
DJ
827 if (tee->magic != &tee_file_magic)
828 internal_error (__FILE__, __LINE__,
e2e0b3e5 829 _("tee_file_isatty: bad magic number"));
172240dd
PA
830
831 return ui_file_isatty (tee->one);
e4c242d9 832}