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