]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/ui-file.c
Replace some xmalloc-family functions with XNEW-family ones
[thirdparty/binutils-gdb.git] / gdb / ui-file.c
CommitLineData
d9fcf2fb 1/* UI_FILE - a generic STDIO like output stream.
349c5d5f 2
32d0add0 3 Copyright (C) 1999-2015 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{
228 ui_file_write (data, buffer, length_buffer);
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{
333 struct accumulated_ui_file *acc = context;
5d502164 334
d9fcf2fb
JM
335 if (acc->buffer == NULL)
336 acc->buffer = xmalloc (length + 1);
337 else
338 acc->buffer = xrealloc (acc->buffer, acc->length + length + 1);
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');
374 return obstack_finish (obstack);
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{
416 struct mem_file *stream = 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{
435 struct mem_file *stream = 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{
448 struct mem_file *stream = 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{
462 struct mem_file *stream = 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;
471 stream->buffer = xmalloc (stream->sizeof_buffer);
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;
481 stream->buffer = xrealloc (stream->buffer, stream->sizeof_buffer);
482 }
483 memcpy (stream->buffer + stream->length_buffer, buffer, length_buffer);
484 stream->length_buffer = new_length;
485 }
486}
487\f
488/* ``struct ui_file'' implementation that maps directly onto
581e13c1 489 <stdio.h>'s FILE. */
d9fcf2fb
JM
490
491static ui_file_write_ftype stdio_file_write;
01124a23 492static ui_file_write_async_safe_ftype stdio_file_write_async_safe;
d9fcf2fb 493static ui_file_fputs_ftype stdio_file_fputs;
449092f6 494static ui_file_read_ftype stdio_file_read;
d9fcf2fb
JM
495static ui_file_isatty_ftype stdio_file_isatty;
496static ui_file_delete_ftype stdio_file_delete;
3e43a32a 497static struct ui_file *stdio_file_new (FILE *file, int close_p);
d9fcf2fb 498static ui_file_flush_ftype stdio_file_flush;
2a9d5ccf 499static ui_file_fseek_ftype stdio_file_fseek;
d9fcf2fb
JM
500
501static int stdio_file_magic;
502
503struct stdio_file
504 {
505 int *magic;
506 FILE *file;
01124a23
DE
507 /* The associated file descriptor is extracted ahead of time for
508 stdio_file_write_async_safe's benefit, in case fileno isn't async-safe. */
509 int fd;
d9fcf2fb
JM
510 int close_p;
511 };
512
513static struct ui_file *
fba45db2 514stdio_file_new (FILE *file, int close_p)
d9fcf2fb
JM
515{
516 struct ui_file *ui_file = ui_file_new ();
8d749320 517 struct stdio_file *stdio = XNEW (struct stdio_file);
5d502164 518
d9fcf2fb
JM
519 stdio->magic = &stdio_file_magic;
520 stdio->file = file;
01124a23 521 stdio->fd = fileno (file);
d9fcf2fb
JM
522 stdio->close_p = close_p;
523 set_ui_file_data (ui_file, stdio, stdio_file_delete);
524 set_ui_file_flush (ui_file, stdio_file_flush);
525 set_ui_file_write (ui_file, stdio_file_write);
01124a23 526 set_ui_file_write_async_safe (ui_file, stdio_file_write_async_safe);
d9fcf2fb 527 set_ui_file_fputs (ui_file, stdio_file_fputs);
449092f6 528 set_ui_file_read (ui_file, stdio_file_read);
d9fcf2fb 529 set_ui_file_isatty (ui_file, stdio_file_isatty);
2a9d5ccf 530 set_ui_file_fseek (ui_file, stdio_file_fseek);
d9fcf2fb
JM
531 return ui_file;
532}
533
534static void
fba45db2 535stdio_file_delete (struct ui_file *file)
d9fcf2fb
JM
536{
537 struct stdio_file *stdio = ui_file_data (file);
5d502164 538
d9fcf2fb 539 if (stdio->magic != &stdio_file_magic)
8e65ff28 540 internal_error (__FILE__, __LINE__,
e2e0b3e5 541 _("stdio_file_delete: bad magic number"));
d9fcf2fb
JM
542 if (stdio->close_p)
543 {
544 fclose (stdio->file);
545 }
b8c9b27d 546 xfree (stdio);
d9fcf2fb
JM
547}
548
549static void
fba45db2 550stdio_file_flush (struct ui_file *file)
d9fcf2fb
JM
551{
552 struct stdio_file *stdio = ui_file_data (file);
5d502164 553
d9fcf2fb 554 if (stdio->magic != &stdio_file_magic)
8e65ff28 555 internal_error (__FILE__, __LINE__,
e2e0b3e5 556 _("stdio_file_flush: bad magic number"));
d9fcf2fb
JM
557 fflush (stdio->file);
558}
559
449092f6
CV
560static long
561stdio_file_read (struct ui_file *file, char *buf, long length_buf)
562{
563 struct stdio_file *stdio = ui_file_data (file);
5d502164 564
449092f6
CV
565 if (stdio->magic != &stdio_file_magic)
566 internal_error (__FILE__, __LINE__,
e2e0b3e5 567 _("stdio_file_read: bad magic number"));
ad960ed2
DJ
568
569 /* For the benefit of Windows, call gdb_select before reading from
570 the file. Wait until at least one byte of data is available.
571 Control-C can interrupt gdb_select, but not read. */
572 {
ad960ed2
DJ
573 fd_set readfds;
574 FD_ZERO (&readfds);
01124a23
DE
575 FD_SET (stdio->fd, &readfds);
576 if (gdb_select (stdio->fd + 1, &readfds, NULL, NULL, NULL) == -1)
ad960ed2
DJ
577 return -1;
578 }
579
01124a23 580 return read (stdio->fd, buf, length_buf);
449092f6
CV
581}
582
d9fcf2fb
JM
583static void
584stdio_file_write (struct ui_file *file, const char *buf, long length_buf)
585{
586 struct stdio_file *stdio = ui_file_data (file);
5d502164 587
d9fcf2fb 588 if (stdio->magic != &stdio_file_magic)
8e65ff28 589 internal_error (__FILE__, __LINE__,
e2e0b3e5 590 _("stdio_file_write: bad magic number"));
bf1d7d9c
JB
591 /* Calling error crashes when we are called from the exception framework. */
592 if (fwrite (buf, length_buf, 1, stdio->file))
d4fb63e1
TT
593 {
594 /* Nothing. */
595 }
d9fcf2fb
JM
596}
597
01124a23
DE
598static void
599stdio_file_write_async_safe (struct ui_file *file,
600 const char *buf, long length_buf)
601{
602 struct stdio_file *stdio = ui_file_data (file);
603
604 if (stdio->magic != &stdio_file_magic)
605 {
606 /* gettext isn't necessarily async safe, so we can't use _("error message") here.
607 We could extract the correct translation ahead of time, but this is an extremely
608 rare event, and one of the other stdio_file_* routines will presumably catch
609 the problem anyway. For now keep it simple and ignore the error here. */
610 return;
611 }
612
9f7bc587
DE
613 /* This is written the way it is to avoid a warning from gcc about not using the
614 result of write (since it can be declared with attribute warn_unused_result).
615 Alas casting to void doesn't work for this. */
093cee7d 616 if (write (stdio->fd, buf, length_buf))
d4fb63e1
TT
617 {
618 /* Nothing. */
619 }
01124a23
DE
620}
621
d9fcf2fb 622static void
fba45db2 623stdio_file_fputs (const char *linebuffer, struct ui_file *file)
d9fcf2fb
JM
624{
625 struct stdio_file *stdio = ui_file_data (file);
5d502164 626
d9fcf2fb 627 if (stdio->magic != &stdio_file_magic)
8e65ff28 628 internal_error (__FILE__, __LINE__,
e2e0b3e5 629 _("stdio_file_fputs: bad magic number"));
bf1d7d9c
JB
630 /* Calling error crashes when we are called from the exception framework. */
631 if (fputs (linebuffer, stdio->file))
d4fb63e1
TT
632 {
633 /* Nothing. */
634 }
d9fcf2fb
JM
635}
636
637static int
fba45db2 638stdio_file_isatty (struct ui_file *file)
d9fcf2fb
JM
639{
640 struct stdio_file *stdio = ui_file_data (file);
5d502164 641
d9fcf2fb 642 if (stdio->magic != &stdio_file_magic)
8e65ff28 643 internal_error (__FILE__, __LINE__,
e2e0b3e5 644 _("stdio_file_isatty: bad magic number"));
01124a23 645 return (isatty (stdio->fd));
d9fcf2fb
JM
646}
647
2a9d5ccf
HZ
648static int
649stdio_file_fseek (struct ui_file *file, long offset, int whence)
650{
651 struct stdio_file *stdio = ui_file_data (file);
652
653 if (stdio->magic != &stdio_file_magic)
654 internal_error (__FILE__, __LINE__,
655 _("stdio_file_fseek: bad magic number"));
656
657 return fseek (stdio->file, offset, whence);
658}
659
ffa4ac95
YQ
660#ifdef __MINGW32__
661/* This is the implementation of ui_file method to_write for stderr.
662 gdb_stdout is flushed before writing to gdb_stderr. */
663
664static void
665stderr_file_write (struct ui_file *file, const char *buf, long length_buf)
666{
667 gdb_flush (gdb_stdout);
668 stdio_file_write (file, buf, length_buf);
669}
670
671/* This is the implementation of ui_file method to_fputs for stderr.
672 gdb_stdout is flushed before writing to gdb_stderr. */
673
674static void
675stderr_file_fputs (const char *linebuffer, struct ui_file *file)
676{
677 gdb_flush (gdb_stdout);
678 stdio_file_fputs (linebuffer, file);
679}
680#endif
681
682struct ui_file *
683stderr_fileopen (void)
684{
685 struct ui_file *ui_file = stdio_fileopen (stderr);
686
687#ifdef __MINGW32__
688 /* There is no real line-buffering on Windows, see
689 http://msdn.microsoft.com/en-us/library/86cebhfs%28v=vs.71%29.aspx
690 so the stdout is either fully-buffered or non-buffered. We can't
691 make stdout non-buffered, because of two concerns,
692 1. non-buffering hurts performance,
693 2. non-buffering may change GDB's behavior when it is interacting
694 with front-end, such as Emacs.
695
696 We decided to leave stdout as fully buffered, but flush it first
697 when something is written to stderr. */
698
699 /* Method 'to_write_async_safe' is not overwritten, because there's
700 no way to flush a stream in an async-safe manner. Fortunately,
701 it doesn't really matter, because:
702 - that method is only used for printing internal debug output
703 from signal handlers.
704 - Windows hosts don't have a concept of async-safeness. Signal
705 handlers run in a separate thread, so they can call
706 the regular non-async-safe output routines freely. */
707 set_ui_file_write (ui_file, stderr_file_write);
708 set_ui_file_fputs (ui_file, stderr_file_fputs);
709#endif
710
711 return ui_file;
712}
713
581e13c1 714/* Like fdopen(). Create a ui_file from a previously opened FILE. */
d9fcf2fb
JM
715
716struct ui_file *
fba45db2 717stdio_fileopen (FILE *file)
d9fcf2fb
JM
718{
719 return stdio_file_new (file, 0);
720}
721
722struct ui_file *
23b3a2c3 723gdb_fopen (const char *name, const char *mode)
d9fcf2fb 724{
614c279d 725 FILE *f = gdb_fopen_cloexec (name, mode);
5d502164 726
d9fcf2fb
JM
727 if (f == NULL)
728 return NULL;
729 return stdio_file_new (f, 1);
730}
e4c242d9
DJ
731
732/* ``struct ui_file'' implementation that maps onto two ui-file objects. */
733
734static ui_file_write_ftype tee_file_write;
735static ui_file_fputs_ftype tee_file_fputs;
736static ui_file_isatty_ftype tee_file_isatty;
737static ui_file_delete_ftype tee_file_delete;
738static ui_file_flush_ftype tee_file_flush;
739
740static int tee_file_magic;
741
742struct tee_file
743 {
744 int *magic;
745 struct ui_file *one, *two;
746 int close_one, close_two;
747 };
748
749struct ui_file *
750tee_file_new (struct ui_file *one, int close_one,
751 struct ui_file *two, int close_two)
752{
753 struct ui_file *ui_file = ui_file_new ();
8d749320 754 struct tee_file *tee = XNEW (struct tee_file);
5d502164 755
e4c242d9
DJ
756 tee->magic = &tee_file_magic;
757 tee->one = one;
758 tee->two = two;
759 tee->close_one = close_one;
760 tee->close_two = close_two;
761 set_ui_file_data (ui_file, tee, tee_file_delete);
762 set_ui_file_flush (ui_file, tee_file_flush);
763 set_ui_file_write (ui_file, tee_file_write);
764 set_ui_file_fputs (ui_file, tee_file_fputs);
765 set_ui_file_isatty (ui_file, tee_file_isatty);
766 return ui_file;
767}
768
769static void
770tee_file_delete (struct ui_file *file)
771{
772 struct tee_file *tee = ui_file_data (file);
5d502164 773
e4c242d9
DJ
774 if (tee->magic != &tee_file_magic)
775 internal_error (__FILE__, __LINE__,
e2e0b3e5 776 _("tee_file_delete: bad magic number"));
e4c242d9
DJ
777 if (tee->close_one)
778 ui_file_delete (tee->one);
779 if (tee->close_two)
780 ui_file_delete (tee->two);
781
782 xfree (tee);
783}
784
785static void
786tee_file_flush (struct ui_file *file)
787{
788 struct tee_file *tee = ui_file_data (file);
5d502164 789
e4c242d9
DJ
790 if (tee->magic != &tee_file_magic)
791 internal_error (__FILE__, __LINE__,
e2e0b3e5 792 _("tee_file_flush: bad magic number"));
e4c242d9
DJ
793 tee->one->to_flush (tee->one);
794 tee->two->to_flush (tee->two);
795}
796
797static void
798tee_file_write (struct ui_file *file, const char *buf, long length_buf)
799{
800 struct tee_file *tee = ui_file_data (file);
5d502164 801
e4c242d9
DJ
802 if (tee->magic != &tee_file_magic)
803 internal_error (__FILE__, __LINE__,
e2e0b3e5 804 _("tee_file_write: bad magic number"));
e4c242d9
DJ
805 ui_file_write (tee->one, buf, length_buf);
806 ui_file_write (tee->two, buf, length_buf);
807}
808
809static void
810tee_file_fputs (const char *linebuffer, struct ui_file *file)
811{
812 struct tee_file *tee = ui_file_data (file);
5d502164 813
e4c242d9
DJ
814 if (tee->magic != &tee_file_magic)
815 internal_error (__FILE__, __LINE__,
e2e0b3e5 816 _("tee_file_fputs: bad magic number"));
e4c242d9
DJ
817 tee->one->to_fputs (linebuffer, tee->one);
818 tee->two->to_fputs (linebuffer, tee->two);
819}
820
821static int
822tee_file_isatty (struct ui_file *file)
823{
824 struct tee_file *tee = ui_file_data (file);
5d502164 825
e4c242d9
DJ
826 if (tee->magic != &tee_file_magic)
827 internal_error (__FILE__, __LINE__,
e2e0b3e5 828 _("tee_file_isatty: bad magic number"));
172240dd
PA
829
830 return ui_file_isatty (tee->one);
e4c242d9 831}