1 /* UI_FILE - a generic STDIO like output stream. 2 3 Copyright (C) 1999-2002, 2007-2012 Free Software Foundation, Inc. 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 9 the Free Software Foundation; either version 3 of the License, or 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 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19 20 /* Implement the ``struct ui_file'' object. */ 21 22 #include "defs.h" 23 #include "ui-file.h" 24 #include "gdb_obstack.h" 25 #include "gdb_string.h" 26 #include "gdb_select.h" 27 28 #include <errno.h> 29 30 static ui_file_isatty_ftype null_file_isatty; 31 static ui_file_write_ftype null_file_write; 32 static ui_file_write_ftype null_file_write_async_safe; 33 static ui_file_fputs_ftype null_file_fputs; 34 static ui_file_read_ftype null_file_read; 35 static ui_file_flush_ftype null_file_flush; 36 static ui_file_delete_ftype null_file_delete; 37 static ui_file_rewind_ftype null_file_rewind; 38 static ui_file_put_ftype null_file_put; 39 40 struct ui_file 41 { 42 int *magic; 43 ui_file_flush_ftype *to_flush; 44 ui_file_write_ftype *to_write; 45 ui_file_write_async_safe_ftype *to_write_async_safe; 46 ui_file_fputs_ftype *to_fputs; 47 ui_file_read_ftype *to_read; 48 ui_file_delete_ftype *to_delete; 49 ui_file_isatty_ftype *to_isatty; 50 ui_file_rewind_ftype *to_rewind; 51 ui_file_put_ftype *to_put; 52 void *to_data; 53 }; 54 int ui_file_magic; 55 56 struct ui_file * 57 ui_file_new (void) 58 { 59 struct ui_file *file = xmalloc (sizeof (struct ui_file)); 60 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); 65 set_ui_file_write_async_safe (file, null_file_write_async_safe); 66 set_ui_file_fputs (file, null_file_fputs); 67 set_ui_file_read (file, null_file_read); 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); 71 return file; 72 } 73 74 void 75 ui_file_delete (struct ui_file *file) 76 { 77 file->to_delete (file); 78 xfree (file); 79 } 80 81 static int 82 null_file_isatty (struct ui_file *file) 83 { 84 return 0; 85 } 86 87 static void 88 null_file_rewind (struct ui_file *file) 89 { 90 return; 91 } 92 93 static void 94 null_file_put (struct ui_file *file, 95 ui_file_put_method_ftype *write, 96 void *dest) 97 { 98 return; 99 } 100 101 static void 102 null_file_flush (struct ui_file *file) 103 { 104 return; 105 } 106 107 static void 108 null_file_write (struct ui_file *file, 109 const char *buf, 110 long sizeof_buf) 111 { 112 if (file->to_fputs == null_file_fputs) 113 /* Both the write and fputs methods are null. Discard the 114 request. */ 115 return; 116 else 117 { 118 /* The fputs method isn't null, slowly pass the write request 119 onto that. FYI, this isn't as bad as it may look - the 120 current (as of 1999-11-07) printf_* function calls fputc and 121 fputc does exactly the below. By having a write function it 122 is possible to clean up that code. */ 123 int i; 124 char b[2]; 125 126 b[1] = '\0'; 127 for (i = 0; i < sizeof_buf; i++) 128 { 129 b[0] = buf[i]; 130 file->to_fputs (b, file); 131 } 132 return; 133 } 134 } 135 136 static long 137 null_file_read (struct ui_file *file, 138 char *buf, 139 long sizeof_buf) 140 { 141 errno = EBADF; 142 return 0; 143 } 144 145 static void 146 null_file_fputs (const char *buf, struct ui_file *file) 147 { 148 if (file->to_write == null_file_write) 149 /* Both the write and fputs methods are null. Discard the 150 request. */ 151 return; 152 else 153 { 154 /* The write method was implemented, use that. */ 155 file->to_write (file, buf, strlen (buf)); 156 } 157 } 158 159 static void 160 null_file_write_async_safe (struct ui_file *file, 161 const char *buf, 162 long sizeof_buf) 163 { 164 return; 165 } 166 167 static void 168 null_file_delete (struct ui_file *file) 169 { 170 return; 171 } 172 173 void * 174 ui_file_data (struct ui_file *file) 175 { 176 if (file->magic != &ui_file_magic) 177 internal_error (__FILE__, __LINE__, 178 _("ui_file_data: bad magic number")); 179 return file->to_data; 180 } 181 182 void 183 gdb_flush (struct ui_file *file) 184 { 185 file->to_flush (file); 186 } 187 188 int 189 ui_file_isatty (struct ui_file *file) 190 { 191 return file->to_isatty (file); 192 } 193 194 void 195 ui_file_rewind (struct ui_file *file) 196 { 197 file->to_rewind (file); 198 } 199 200 void 201 ui_file_put (struct ui_file *file, 202 ui_file_put_method_ftype *write, 203 void *dest) 204 { 205 file->to_put (file, write, dest); 206 } 207 208 void 209 ui_file_write (struct ui_file *file, 210 const char *buf, 211 long length_buf) 212 { 213 file->to_write (file, buf, length_buf); 214 } 215 216 void 217 ui_file_write_async_safe (struct ui_file *file, 218 const char *buf, 219 long length_buf) 220 { 221 file->to_write_async_safe (file, buf, length_buf); 222 } 223 224 long 225 ui_file_read (struct ui_file *file, char *buf, long length_buf) 226 { 227 return file->to_read (file, buf, length_buf); 228 } 229 230 void 231 fputs_unfiltered (const char *buf, struct ui_file *file) 232 { 233 file->to_fputs (buf, file); 234 } 235 236 void 237 set_ui_file_flush (struct ui_file *file, ui_file_flush_ftype *flush) 238 { 239 file->to_flush = flush; 240 } 241 242 void 243 set_ui_file_isatty (struct ui_file *file, ui_file_isatty_ftype *isatty) 244 { 245 file->to_isatty = isatty; 246 } 247 248 void 249 set_ui_file_rewind (struct ui_file *file, ui_file_rewind_ftype *rewind) 250 { 251 file->to_rewind = rewind; 252 } 253 254 void 255 set_ui_file_put (struct ui_file *file, ui_file_put_ftype *put) 256 { 257 file->to_put = put; 258 } 259 260 void 261 set_ui_file_write (struct ui_file *file, 262 ui_file_write_ftype *write) 263 { 264 file->to_write = write; 265 } 266 267 void 268 set_ui_file_write_async_safe (struct ui_file *file, 269 ui_file_write_async_safe_ftype *write_async_safe) 270 { 271 file->to_write_async_safe = write_async_safe; 272 } 273 274 void 275 set_ui_file_read (struct ui_file *file, ui_file_read_ftype *read) 276 { 277 file->to_read = read; 278 } 279 280 void 281 set_ui_file_fputs (struct ui_file *file, ui_file_fputs_ftype *fputs) 282 { 283 file->to_fputs = fputs; 284 } 285 286 void 287 set_ui_file_data (struct ui_file *file, void *data, 288 ui_file_delete_ftype *delete) 289 { 290 file->to_data = data; 291 file->to_delete = delete; 292 } 293 294 /* ui_file utility function for converting a ``struct ui_file'' into 295 a memory buffer. */ 296 297 struct accumulated_ui_file 298 { 299 char *buffer; 300 long length; 301 }; 302 303 static void 304 do_ui_file_xstrdup (void *context, const char *buffer, long length) 305 { 306 struct accumulated_ui_file *acc = context; 307 308 if (acc->buffer == NULL) 309 acc->buffer = xmalloc (length + 1); 310 else 311 acc->buffer = xrealloc (acc->buffer, acc->length + length + 1); 312 memcpy (acc->buffer + acc->length, buffer, length); 313 acc->length += length; 314 acc->buffer[acc->length] = '\0'; 315 } 316 317 char * 318 ui_file_xstrdup (struct ui_file *file, long *length) 319 { 320 struct accumulated_ui_file acc; 321 322 acc.buffer = NULL; 323 acc.length = 0; 324 ui_file_put (file, do_ui_file_xstrdup, &acc); 325 if (acc.buffer == NULL) 326 acc.buffer = xstrdup (""); 327 if (length != NULL) 328 *length = acc.length; 329 return acc.buffer; 330 } 331 332 static void 333 do_ui_file_obsavestring (void *context, const char *buffer, long length) 334 { 335 struct obstack *obstack = (struct obstack *) context; 336 337 obstack_grow (obstack, buffer, length); 338 } 339 340 char * 341 ui_file_obsavestring (struct ui_file *file, struct obstack *obstack, 342 long *length) 343 { 344 ui_file_put (file, do_ui_file_obsavestring, obstack); 345 *length = obstack_object_size (obstack); 346 obstack_1grow (obstack, '\0'); 347 return obstack_finish (obstack); 348 } 349 350 /* A pure memory based ``struct ui_file'' that can be used an output 351 buffer. The buffers accumulated contents are available via 352 ui_file_put(). */ 353 354 struct mem_file 355 { 356 int *magic; 357 char *buffer; 358 int sizeof_buffer; 359 int length_buffer; 360 }; 361 362 static ui_file_rewind_ftype mem_file_rewind; 363 static ui_file_put_ftype mem_file_put; 364 static ui_file_write_ftype mem_file_write; 365 static ui_file_delete_ftype mem_file_delete; 366 static struct ui_file *mem_file_new (void); 367 static int mem_file_magic; 368 369 static struct ui_file * 370 mem_file_new (void) 371 { 372 struct mem_file *stream = XMALLOC (struct mem_file); 373 struct ui_file *file = ui_file_new (); 374 375 set_ui_file_data (file, stream, mem_file_delete); 376 set_ui_file_rewind (file, mem_file_rewind); 377 set_ui_file_put (file, mem_file_put); 378 set_ui_file_write (file, mem_file_write); 379 stream->magic = &mem_file_magic; 380 stream->buffer = NULL; 381 stream->sizeof_buffer = 0; 382 stream->length_buffer = 0; 383 return file; 384 } 385 386 static void 387 mem_file_delete (struct ui_file *file) 388 { 389 struct mem_file *stream = ui_file_data (file); 390 391 if (stream->magic != &mem_file_magic) 392 internal_error (__FILE__, __LINE__, 393 _("mem_file_delete: bad magic number")); 394 if (stream->buffer != NULL) 395 xfree (stream->buffer); 396 xfree (stream); 397 } 398 399 struct ui_file * 400 mem_fileopen (void) 401 { 402 return mem_file_new (); 403 } 404 405 static void 406 mem_file_rewind (struct ui_file *file) 407 { 408 struct mem_file *stream = ui_file_data (file); 409 410 if (stream->magic != &mem_file_magic) 411 internal_error (__FILE__, __LINE__, 412 _("mem_file_rewind: bad magic number")); 413 stream->length_buffer = 0; 414 } 415 416 static void 417 mem_file_put (struct ui_file *file, 418 ui_file_put_method_ftype *write, 419 void *dest) 420 { 421 struct mem_file *stream = ui_file_data (file); 422 423 if (stream->magic != &mem_file_magic) 424 internal_error (__FILE__, __LINE__, 425 _("mem_file_put: bad magic number")); 426 if (stream->length_buffer > 0) 427 write (dest, stream->buffer, stream->length_buffer); 428 } 429 430 void 431 mem_file_write (struct ui_file *file, 432 const char *buffer, 433 long length_buffer) 434 { 435 struct mem_file *stream = ui_file_data (file); 436 437 if (stream->magic != &mem_file_magic) 438 internal_error (__FILE__, __LINE__, 439 _("mem_file_write: bad magic number")); 440 if (stream->buffer == NULL) 441 { 442 stream->length_buffer = length_buffer; 443 stream->sizeof_buffer = length_buffer; 444 stream->buffer = xmalloc (stream->sizeof_buffer); 445 memcpy (stream->buffer, buffer, length_buffer); 446 } 447 else 448 { 449 int new_length = stream->length_buffer + length_buffer; 450 451 if (new_length >= stream->sizeof_buffer) 452 { 453 stream->sizeof_buffer = new_length; 454 stream->buffer = xrealloc (stream->buffer, stream->sizeof_buffer); 455 } 456 memcpy (stream->buffer + stream->length_buffer, buffer, length_buffer); 457 stream->length_buffer = new_length; 458 } 459 } 460 461 /* ``struct ui_file'' implementation that maps directly onto 462 <stdio.h>'s FILE. */ 463 464 static ui_file_write_ftype stdio_file_write; 465 static ui_file_write_async_safe_ftype stdio_file_write_async_safe; 466 static ui_file_fputs_ftype stdio_file_fputs; 467 static ui_file_read_ftype stdio_file_read; 468 static ui_file_isatty_ftype stdio_file_isatty; 469 static ui_file_delete_ftype stdio_file_delete; 470 static struct ui_file *stdio_file_new (FILE *file, int close_p); 471 static ui_file_flush_ftype stdio_file_flush; 472 473 static int stdio_file_magic; 474 475 struct stdio_file 476 { 477 int *magic; 478 FILE *file; 479 /* The associated file descriptor is extracted ahead of time for 480 stdio_file_write_async_safe's benefit, in case fileno isn't async-safe. */ 481 int fd; 482 int close_p; 483 }; 484 485 static struct ui_file * 486 stdio_file_new (FILE *file, int close_p) 487 { 488 struct ui_file *ui_file = ui_file_new (); 489 struct stdio_file *stdio = xmalloc (sizeof (struct stdio_file)); 490 491 stdio->magic = &stdio_file_magic; 492 stdio->file = file; 493 stdio->fd = fileno (file); 494 stdio->close_p = close_p; 495 set_ui_file_data (ui_file, stdio, stdio_file_delete); 496 set_ui_file_flush (ui_file, stdio_file_flush); 497 set_ui_file_write (ui_file, stdio_file_write); 498 set_ui_file_write_async_safe (ui_file, stdio_file_write_async_safe); 499 set_ui_file_fputs (ui_file, stdio_file_fputs); 500 set_ui_file_read (ui_file, stdio_file_read); 501 set_ui_file_isatty (ui_file, stdio_file_isatty); 502 return ui_file; 503 } 504 505 static void 506 stdio_file_delete (struct ui_file *file) 507 { 508 struct stdio_file *stdio = ui_file_data (file); 509 510 if (stdio->magic != &stdio_file_magic) 511 internal_error (__FILE__, __LINE__, 512 _("stdio_file_delete: bad magic number")); 513 if (stdio->close_p) 514 { 515 fclose (stdio->file); 516 } 517 xfree (stdio); 518 } 519 520 static void 521 stdio_file_flush (struct ui_file *file) 522 { 523 struct stdio_file *stdio = ui_file_data (file); 524 525 if (stdio->magic != &stdio_file_magic) 526 internal_error (__FILE__, __LINE__, 527 _("stdio_file_flush: bad magic number")); 528 fflush (stdio->file); 529 } 530 531 static long 532 stdio_file_read (struct ui_file *file, char *buf, long length_buf) 533 { 534 struct stdio_file *stdio = ui_file_data (file); 535 536 if (stdio->magic != &stdio_file_magic) 537 internal_error (__FILE__, __LINE__, 538 _("stdio_file_read: bad magic number")); 539 540 /* For the benefit of Windows, call gdb_select before reading from 541 the file. Wait until at least one byte of data is available. 542 Control-C can interrupt gdb_select, but not read. */ 543 { 544 fd_set readfds; 545 FD_ZERO (&readfds); 546 FD_SET (stdio->fd, &readfds); 547 if (gdb_select (stdio->fd + 1, &readfds, NULL, NULL, NULL) == -1) 548 return -1; 549 } 550 551 return read (stdio->fd, buf, length_buf); 552 } 553 554 static void 555 stdio_file_write (struct ui_file *file, const char *buf, long length_buf) 556 { 557 struct stdio_file *stdio = ui_file_data (file); 558 559 if (stdio->magic != &stdio_file_magic) 560 internal_error (__FILE__, __LINE__, 561 _("stdio_file_write: bad magic number")); 562 /* Calling error crashes when we are called from the exception framework. */ 563 if (fwrite (buf, length_buf, 1, stdio->file)) 564 ; 565 } 566 567 static void 568 stdio_file_write_async_safe (struct ui_file *file, 569 const char *buf, long length_buf) 570 { 571 struct stdio_file *stdio = ui_file_data (file); 572 573 if (stdio->magic != &stdio_file_magic) 574 { 575 /* gettext isn't necessarily async safe, so we can't use _("error message") here. 576 We could extract the correct translation ahead of time, but this is an extremely 577 rare event, and one of the other stdio_file_* routines will presumably catch 578 the problem anyway. For now keep it simple and ignore the error here. */ 579 return; 580 } 581 582 /* This is written the way it is to avoid a warning from gcc about not using the 583 result of write (since it can be declared with attribute warn_unused_result). 584 Alas casting to void doesn't work for this. */ 585 if (write (stdio->fd, buf, length_buf)) 586 ; 587 } 588 589 static void 590 stdio_file_fputs (const char *linebuffer, struct ui_file *file) 591 { 592 struct stdio_file *stdio = ui_file_data (file); 593 594 if (stdio->magic != &stdio_file_magic) 595 internal_error (__FILE__, __LINE__, 596 _("stdio_file_fputs: bad magic number")); 597 /* Calling error crashes when we are called from the exception framework. */ 598 if (fputs (linebuffer, stdio->file)) 599 ; 600 } 601 602 static int 603 stdio_file_isatty (struct ui_file *file) 604 { 605 struct stdio_file *stdio = ui_file_data (file); 606 607 if (stdio->magic != &stdio_file_magic) 608 internal_error (__FILE__, __LINE__, 609 _("stdio_file_isatty: bad magic number")); 610 return (isatty (stdio->fd)); 611 } 612 613 /* Like fdopen(). Create a ui_file from a previously opened FILE. */ 614 615 struct ui_file * 616 stdio_fileopen (FILE *file) 617 { 618 return stdio_file_new (file, 0); 619 } 620 621 struct ui_file * 622 gdb_fopen (char *name, char *mode) 623 { 624 FILE *f = fopen (name, mode); 625 626 if (f == NULL) 627 return NULL; 628 return stdio_file_new (f, 1); 629 } 630 631 /* ``struct ui_file'' implementation that maps onto two ui-file objects. */ 632 633 static ui_file_write_ftype tee_file_write; 634 static ui_file_fputs_ftype tee_file_fputs; 635 static ui_file_isatty_ftype tee_file_isatty; 636 static ui_file_delete_ftype tee_file_delete; 637 static ui_file_flush_ftype tee_file_flush; 638 639 static int tee_file_magic; 640 641 struct tee_file 642 { 643 int *magic; 644 struct ui_file *one, *two; 645 int close_one, close_two; 646 }; 647 648 struct ui_file * 649 tee_file_new (struct ui_file *one, int close_one, 650 struct ui_file *two, int close_two) 651 { 652 struct ui_file *ui_file = ui_file_new (); 653 struct tee_file *tee = xmalloc (sizeof (struct tee_file)); 654 655 tee->magic = &tee_file_magic; 656 tee->one = one; 657 tee->two = two; 658 tee->close_one = close_one; 659 tee->close_two = close_two; 660 set_ui_file_data (ui_file, tee, tee_file_delete); 661 set_ui_file_flush (ui_file, tee_file_flush); 662 set_ui_file_write (ui_file, tee_file_write); 663 set_ui_file_fputs (ui_file, tee_file_fputs); 664 set_ui_file_isatty (ui_file, tee_file_isatty); 665 return ui_file; 666 } 667 668 static void 669 tee_file_delete (struct ui_file *file) 670 { 671 struct tee_file *tee = ui_file_data (file); 672 673 if (tee->magic != &tee_file_magic) 674 internal_error (__FILE__, __LINE__, 675 _("tee_file_delete: bad magic number")); 676 if (tee->close_one) 677 ui_file_delete (tee->one); 678 if (tee->close_two) 679 ui_file_delete (tee->two); 680 681 xfree (tee); 682 } 683 684 static void 685 tee_file_flush (struct ui_file *file) 686 { 687 struct tee_file *tee = ui_file_data (file); 688 689 if (tee->magic != &tee_file_magic) 690 internal_error (__FILE__, __LINE__, 691 _("tee_file_flush: bad magic number")); 692 tee->one->to_flush (tee->one); 693 tee->two->to_flush (tee->two); 694 } 695 696 static void 697 tee_file_write (struct ui_file *file, const char *buf, long length_buf) 698 { 699 struct tee_file *tee = ui_file_data (file); 700 701 if (tee->magic != &tee_file_magic) 702 internal_error (__FILE__, __LINE__, 703 _("tee_file_write: bad magic number")); 704 ui_file_write (tee->one, buf, length_buf); 705 ui_file_write (tee->two, buf, length_buf); 706 } 707 708 static void 709 tee_file_fputs (const char *linebuffer, struct ui_file *file) 710 { 711 struct tee_file *tee = ui_file_data (file); 712 713 if (tee->magic != &tee_file_magic) 714 internal_error (__FILE__, __LINE__, 715 _("tee_file_fputs: bad magic number")); 716 tee->one->to_fputs (linebuffer, tee->one); 717 tee->two->to_fputs (linebuffer, tee->two); 718 } 719 720 static int 721 tee_file_isatty (struct ui_file *file) 722 { 723 struct tee_file *tee = ui_file_data (file); 724 725 if (tee->magic != &tee_file_magic) 726 internal_error (__FILE__, __LINE__, 727 _("tee_file_isatty: bad magic number")); 728 729 return ui_file_isatty (tee->one); 730 } 731