| Index: gdb/ui-file.c
|
| diff --git a/gdb/ui-file.c b/gdb/ui-file.c
|
| index 8528793c74de2d1547dd0c9b3acd0f9776114683..af6c22e4312d716e269623069d5a0d80974f344f 100644
|
| --- a/gdb/ui-file.c
|
| +++ b/gdb/ui-file.c
|
| @@ -1,6 +1,6 @@
|
| /* UI_FILE - a generic STDIO like output stream.
|
|
|
| - Copyright (C) 1999-2002, 2007-2012 Free Software Foundation, Inc.
|
| + Copyright (C) 1999-2013 Free Software Foundation, Inc.
|
|
|
| This file is part of GDB.
|
|
|
| @@ -22,8 +22,9 @@
|
| #include "defs.h"
|
| #include "ui-file.h"
|
| #include "gdb_obstack.h"
|
| -#include "gdb_string.h"
|
| +#include <string.h>
|
| #include "gdb_select.h"
|
| +#include "filestuff.h"
|
|
|
| #include <errno.h>
|
|
|
| @@ -36,6 +37,7 @@ static ui_file_flush_ftype null_file_flush;
|
| static ui_file_delete_ftype null_file_delete;
|
| static ui_file_rewind_ftype null_file_rewind;
|
| static ui_file_put_ftype null_file_put;
|
| +static ui_file_fseek_ftype null_file_fseek;
|
|
|
| struct ui_file
|
| {
|
| @@ -49,6 +51,7 @@ struct ui_file
|
| ui_file_isatty_ftype *to_isatty;
|
| ui_file_rewind_ftype *to_rewind;
|
| ui_file_put_ftype *to_put;
|
| + ui_file_fseek_ftype *to_fseek;
|
| void *to_data;
|
| };
|
| int ui_file_magic;
|
| @@ -68,6 +71,7 @@ ui_file_new (void)
|
| set_ui_file_isatty (file, null_file_isatty);
|
| set_ui_file_rewind (file, null_file_rewind);
|
| set_ui_file_put (file, null_file_put);
|
| + set_ui_file_fseek (file, null_file_fseek);
|
| return file;
|
| }
|
|
|
| @@ -170,6 +174,14 @@ null_file_delete (struct ui_file *file)
|
| return;
|
| }
|
|
|
| +static int
|
| +null_file_fseek (struct ui_file *stream, long offset, int whence)
|
| +{
|
| + errno = EBADF;
|
| +
|
| + return -1;
|
| +}
|
| +
|
| void *
|
| ui_file_data (struct ui_file *file)
|
| {
|
| @@ -227,6 +239,12 @@ ui_file_read (struct ui_file *file, char *buf, long length_buf)
|
| return file->to_read (file, buf, length_buf);
|
| }
|
|
|
| +int
|
| +ui_file_fseek (struct ui_file *file, long offset, int whence)
|
| +{
|
| + return file->to_fseek (file, offset, whence);
|
| +}
|
| +
|
| void
|
| fputs_unfiltered (const char *buf, struct ui_file *file)
|
| {
|
| @@ -234,61 +252,67 @@ fputs_unfiltered (const char *buf, struct ui_file *file)
|
| }
|
|
|
| void
|
| -set_ui_file_flush (struct ui_file *file, ui_file_flush_ftype *flush)
|
| +set_ui_file_flush (struct ui_file *file, ui_file_flush_ftype *flush_ptr)
|
| {
|
| - file->to_flush = flush;
|
| + file->to_flush = flush_ptr;
|
| }
|
|
|
| void
|
| -set_ui_file_isatty (struct ui_file *file, ui_file_isatty_ftype *isatty)
|
| +set_ui_file_isatty (struct ui_file *file, ui_file_isatty_ftype *isatty_ptr)
|
| {
|
| - file->to_isatty = isatty;
|
| + file->to_isatty = isatty_ptr;
|
| }
|
|
|
| void
|
| -set_ui_file_rewind (struct ui_file *file, ui_file_rewind_ftype *rewind)
|
| +set_ui_file_rewind (struct ui_file *file, ui_file_rewind_ftype *rewind_ptr)
|
| {
|
| - file->to_rewind = rewind;
|
| + file->to_rewind = rewind_ptr;
|
| }
|
|
|
| void
|
| -set_ui_file_put (struct ui_file *file, ui_file_put_ftype *put)
|
| +set_ui_file_put (struct ui_file *file, ui_file_put_ftype *put_ptr)
|
| {
|
| - file->to_put = put;
|
| + file->to_put = put_ptr;
|
| }
|
|
|
| void
|
| set_ui_file_write (struct ui_file *file,
|
| - ui_file_write_ftype *write)
|
| + ui_file_write_ftype *write_ptr)
|
| {
|
| - file->to_write = write;
|
| + file->to_write = write_ptr;
|
| }
|
|
|
| void
|
| set_ui_file_write_async_safe (struct ui_file *file,
|
| - ui_file_write_async_safe_ftype *write_async_safe)
|
| + ui_file_write_async_safe_ftype *write_async_safe_ptr)
|
| +{
|
| + file->to_write_async_safe = write_async_safe_ptr;
|
| +}
|
| +
|
| +void
|
| +set_ui_file_read (struct ui_file *file, ui_file_read_ftype *read_ptr)
|
| {
|
| - file->to_write_async_safe = write_async_safe;
|
| + file->to_read = read_ptr;
|
| }
|
|
|
| void
|
| -set_ui_file_read (struct ui_file *file, ui_file_read_ftype *read)
|
| +set_ui_file_fputs (struct ui_file *file, ui_file_fputs_ftype *fputs_ptr)
|
| {
|
| - file->to_read = read;
|
| + file->to_fputs = fputs_ptr;
|
| }
|
|
|
| void
|
| -set_ui_file_fputs (struct ui_file *file, ui_file_fputs_ftype *fputs)
|
| +set_ui_file_fseek (struct ui_file *file, ui_file_fseek_ftype *fseek_ptr)
|
| {
|
| - file->to_fputs = fputs;
|
| + file->to_fseek = fseek_ptr;
|
| }
|
|
|
| void
|
| set_ui_file_data (struct ui_file *file, void *data,
|
| - ui_file_delete_ftype *delete)
|
| + ui_file_delete_ftype *delete_ptr)
|
| {
|
| file->to_data = data;
|
| - file->to_delete = delete;
|
| + file->to_delete = delete_ptr;
|
| }
|
|
|
| /* ui_file utility function for converting a ``struct ui_file'' into
|
| @@ -469,6 +493,7 @@ static ui_file_isatty_ftype stdio_file_isatty;
|
| static ui_file_delete_ftype stdio_file_delete;
|
| static struct ui_file *stdio_file_new (FILE *file, int close_p);
|
| static ui_file_flush_ftype stdio_file_flush;
|
| +static ui_file_fseek_ftype stdio_file_fseek;
|
|
|
| static int stdio_file_magic;
|
|
|
| @@ -499,6 +524,7 @@ stdio_file_new (FILE *file, int close_p)
|
| set_ui_file_fputs (ui_file, stdio_file_fputs);
|
| set_ui_file_read (ui_file, stdio_file_read);
|
| set_ui_file_isatty (ui_file, stdio_file_isatty);
|
| + set_ui_file_fseek (ui_file, stdio_file_fseek);
|
| return ui_file;
|
| }
|
|
|
| @@ -561,7 +587,9 @@ stdio_file_write (struct ui_file *file, const char *buf, long length_buf)
|
| _("stdio_file_write: bad magic number"));
|
| /* Calling error crashes when we are called from the exception framework. */
|
| if (fwrite (buf, length_buf, 1, stdio->file))
|
| - ;
|
| + {
|
| + /* Nothing. */
|
| + }
|
| }
|
|
|
| static void
|
| @@ -583,7 +611,9 @@ stdio_file_write_async_safe (struct ui_file *file,
|
| result of write (since it can be declared with attribute warn_unused_result).
|
| Alas casting to void doesn't work for this. */
|
| if (write (stdio->fd, buf, length_buf))
|
| - ;
|
| + {
|
| + /* Nothing. */
|
| + }
|
| }
|
|
|
| static void
|
| @@ -596,7 +626,9 @@ stdio_file_fputs (const char *linebuffer, struct ui_file *file)
|
| _("stdio_file_fputs: bad magic number"));
|
| /* Calling error crashes when we are called from the exception framework. */
|
| if (fputs (linebuffer, stdio->file))
|
| - ;
|
| + {
|
| + /* Nothing. */
|
| + }
|
| }
|
|
|
| static int
|
| @@ -610,6 +642,72 @@ stdio_file_isatty (struct ui_file *file)
|
| return (isatty (stdio->fd));
|
| }
|
|
|
| +static int
|
| +stdio_file_fseek (struct ui_file *file, long offset, int whence)
|
| +{
|
| + struct stdio_file *stdio = ui_file_data (file);
|
| +
|
| + if (stdio->magic != &stdio_file_magic)
|
| + internal_error (__FILE__, __LINE__,
|
| + _("stdio_file_fseek: bad magic number"));
|
| +
|
| + return fseek (stdio->file, offset, whence);
|
| +}
|
| +
|
| +#ifdef __MINGW32__
|
| +/* This is the implementation of ui_file method to_write for stderr.
|
| + gdb_stdout is flushed before writing to gdb_stderr. */
|
| +
|
| +static void
|
| +stderr_file_write (struct ui_file *file, const char *buf, long length_buf)
|
| +{
|
| + gdb_flush (gdb_stdout);
|
| + stdio_file_write (file, buf, length_buf);
|
| +}
|
| +
|
| +/* This is the implementation of ui_file method to_fputs for stderr.
|
| + gdb_stdout is flushed before writing to gdb_stderr. */
|
| +
|
| +static void
|
| +stderr_file_fputs (const char *linebuffer, struct ui_file *file)
|
| +{
|
| + gdb_flush (gdb_stdout);
|
| + stdio_file_fputs (linebuffer, file);
|
| +}
|
| +#endif
|
| +
|
| +struct ui_file *
|
| +stderr_fileopen (void)
|
| +{
|
| + struct ui_file *ui_file = stdio_fileopen (stderr);
|
| +
|
| +#ifdef __MINGW32__
|
| + /* There is no real line-buffering on Windows, see
|
| + http://msdn.microsoft.com/en-us/library/86cebhfs%28v=vs.71%29.aspx
|
| + so the stdout is either fully-buffered or non-buffered. We can't
|
| + make stdout non-buffered, because of two concerns,
|
| + 1. non-buffering hurts performance,
|
| + 2. non-buffering may change GDB's behavior when it is interacting
|
| + with front-end, such as Emacs.
|
| +
|
| + We decided to leave stdout as fully buffered, but flush it first
|
| + when something is written to stderr. */
|
| +
|
| + /* Method 'to_write_async_safe' is not overwritten, because there's
|
| + no way to flush a stream in an async-safe manner. Fortunately,
|
| + it doesn't really matter, because:
|
| + - that method is only used for printing internal debug output
|
| + from signal handlers.
|
| + - Windows hosts don't have a concept of async-safeness. Signal
|
| + handlers run in a separate thread, so they can call
|
| + the regular non-async-safe output routines freely. */
|
| + set_ui_file_write (ui_file, stderr_file_write);
|
| + set_ui_file_fputs (ui_file, stderr_file_fputs);
|
| +#endif
|
| +
|
| + return ui_file;
|
| +}
|
| +
|
| /* Like fdopen(). Create a ui_file from a previously opened FILE. */
|
|
|
| struct ui_file *
|
| @@ -619,9 +717,9 @@ stdio_fileopen (FILE *file)
|
| }
|
|
|
| struct ui_file *
|
| -gdb_fopen (char *name, char *mode)
|
| +gdb_fopen (const char *name, const char *mode)
|
| {
|
| - FILE *f = fopen (name, mode);
|
| + FILE *f = gdb_fopen_cloexec (name, mode);
|
|
|
| if (f == NULL)
|
| return NULL;
|
|
|