*** empty log message ***
[deliverable/binutils-gdb.git] / gdb / ui-file.c
index 8adcf891e35b0882c591a7a211724d8eafc36f7d..8528793c74de2d1547dd0c9b3acd0f9776114683 100644 (file)
@@ -1,7 +1,6 @@
 /* UI_FILE - a generic STDIO like output stream.
 
-   Copyright (C) 1999, 2000, 2001, 2002, 2007, 2008, 2009, 2010, 2011
-   Free Software Foundation, Inc.
+   Copyright (C) 1999-2002, 2007-2012 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -18,7 +17,7 @@
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
-/* Implement the ``struct ui_file'' object. */
+/* Implement the ``struct ui_file'' object.  */
 
 #include "defs.h"
 #include "ui-file.h"
@@ -30,6 +29,7 @@
 
 static ui_file_isatty_ftype null_file_isatty;
 static ui_file_write_ftype null_file_write;
+static ui_file_write_ftype null_file_write_async_safe;
 static ui_file_fputs_ftype null_file_fputs;
 static ui_file_read_ftype null_file_read;
 static ui_file_flush_ftype null_file_flush;
@@ -42,6 +42,7 @@ struct ui_file
     int *magic;
     ui_file_flush_ftype *to_flush;
     ui_file_write_ftype *to_write;
+    ui_file_write_async_safe_ftype *to_write_async_safe;
     ui_file_fputs_ftype *to_fputs;
     ui_file_read_ftype *to_read;
     ui_file_delete_ftype *to_delete;
@@ -61,6 +62,7 @@ ui_file_new (void)
   set_ui_file_data (file, NULL, null_file_delete);
   set_ui_file_flush (file, null_file_flush);
   set_ui_file_write (file, null_file_write);
+  set_ui_file_write_async_safe (file, null_file_write_async_safe);
   set_ui_file_fputs (file, null_file_fputs);
   set_ui_file_read (file, null_file_read);
   set_ui_file_isatty (file, null_file_isatty);
@@ -108,8 +110,8 @@ null_file_write (struct ui_file *file,
                 long sizeof_buf)
 {
   if (file->to_fputs == null_file_fputs)
-    /* Both the write and fputs methods are null. Discard the
-       request. */
+    /* Both the write and fputs methods are null.  Discard the
+       request.  */
     return;
   else
     {
@@ -144,16 +146,24 @@ static void
 null_file_fputs (const char *buf, struct ui_file *file)
 {
   if (file->to_write == null_file_write)
-    /* Both the write and fputs methods are null. Discard the
-       request. */
+    /* Both the write and fputs methods are null.  Discard the
+       request.  */
     return;
   else
     {
-      /* The write method was implemented, use that. */
+      /* The write method was implemented, use that.  */
       file->to_write (file, buf, strlen (buf));
     }
 }
 
+static void
+null_file_write_async_safe (struct ui_file *file,
+                           const char *buf,
+                           long sizeof_buf)
+{
+  return;
+}
+
 static void
 null_file_delete (struct ui_file *file)
 {
@@ -203,6 +213,14 @@ ui_file_write (struct ui_file *file,
   file->to_write (file, buf, length_buf);
 }
 
+void
+ui_file_write_async_safe (struct ui_file *file,
+                         const char *buf,
+                         long length_buf)
+{
+  file->to_write_async_safe (file, buf, length_buf);
+}
+
 long
 ui_file_read (struct ui_file *file, char *buf, long length_buf)
 {
@@ -246,6 +264,13 @@ set_ui_file_write (struct ui_file *file,
   file->to_write = write;
 }
 
+void
+set_ui_file_write_async_safe (struct ui_file *file,
+                             ui_file_write_async_safe_ftype *write_async_safe)
+{
+  file->to_write_async_safe = write_async_safe;
+}
+
 void
 set_ui_file_read (struct ui_file *file, ui_file_read_ftype *read)
 {
@@ -267,7 +292,7 @@ set_ui_file_data (struct ui_file *file, void *data,
 }
 
 /* ui_file utility function for converting a ``struct ui_file'' into
-   a memory buffer. */
+   a memory buffer.  */
 
 struct accumulated_ui_file
 {
@@ -323,8 +348,8 @@ ui_file_obsavestring (struct ui_file *file, struct obstack *obstack,
 }
 \f
 /* A pure memory based ``struct ui_file'' that can be used an output
-   buffer. The buffers accumulated contents are available via
-   ui_file_put(). */
+   buffer.  The buffers accumulated contents are available via
+   ui_file_put().  */
 
 struct mem_file
   {
@@ -434,9 +459,10 @@ mem_file_write (struct ui_file *file,
 }
 \f
 /* ``struct ui_file'' implementation that maps directly onto
-   <stdio.h>'s FILE. */
+   <stdio.h>'s FILE.  */
 
 static ui_file_write_ftype stdio_file_write;
+static ui_file_write_async_safe_ftype stdio_file_write_async_safe;
 static ui_file_fputs_ftype stdio_file_fputs;
 static ui_file_read_ftype stdio_file_read;
 static ui_file_isatty_ftype stdio_file_isatty;
@@ -450,6 +476,9 @@ struct stdio_file
   {
     int *magic;
     FILE *file;
+    /* The associated file descriptor is extracted ahead of time for
+       stdio_file_write_async_safe's benefit, in case fileno isn't async-safe.  */
+    int fd;
     int close_p;
   };
 
@@ -461,10 +490,12 @@ stdio_file_new (FILE *file, int close_p)
 
   stdio->magic = &stdio_file_magic;
   stdio->file = file;
+  stdio->fd = fileno (file);
   stdio->close_p = close_p;
   set_ui_file_data (ui_file, stdio, stdio_file_delete);
   set_ui_file_flush (ui_file, stdio_file_flush);
   set_ui_file_write (ui_file, stdio_file_write);
+  set_ui_file_write_async_safe (ui_file, stdio_file_write_async_safe);
   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);
@@ -510,16 +541,14 @@ stdio_file_read (struct ui_file *file, char *buf, long length_buf)
      the file.  Wait until at least one byte of data is available.
      Control-C can interrupt gdb_select, but not read.  */
   {
-    int fd = fileno (stdio->file);
-
     fd_set readfds;
     FD_ZERO (&readfds);
-    FD_SET (fd, &readfds);
-    if (gdb_select (fd + 1, &readfds, NULL, NULL, NULL) == -1)
+    FD_SET (stdio->fd, &readfds);
+    if (gdb_select (stdio->fd + 1, &readfds, NULL, NULL, NULL) == -1)
       return -1;
   }
 
-  return read (fileno (stdio->file), buf, length_buf);
+  return read (stdio->fd, buf, length_buf);
 }
 
 static void
@@ -535,6 +564,28 @@ stdio_file_write (struct ui_file *file, const char *buf, long length_buf)
     ;
 }
 
+static void
+stdio_file_write_async_safe (struct ui_file *file,
+                            const char *buf, long length_buf)
+{
+  struct stdio_file *stdio = ui_file_data (file);
+
+  if (stdio->magic != &stdio_file_magic)
+    {
+      /* gettext isn't necessarily async safe, so we can't use _("error message") here.
+        We could extract the correct translation ahead of time, but this is an extremely
+        rare event, and one of the other stdio_file_* routines will presumably catch
+        the problem anyway.  For now keep it simple and ignore the error here.  */
+      return;
+    }
+
+  /* This is written the way it is to avoid a warning from gcc about not using the
+     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))
+    ;
+}
+
 static void
 stdio_file_fputs (const char *linebuffer, struct ui_file *file)
 {
@@ -556,10 +607,10 @@ stdio_file_isatty (struct ui_file *file)
   if (stdio->magic != &stdio_file_magic)
     internal_error (__FILE__, __LINE__,
                    _("stdio_file_isatty: bad magic number"));
-  return (isatty (fileno (stdio->file)));
+  return (isatty (stdio->fd));
 }
 
-/* Like fdopen().  Create a ui_file from a previously opened FILE. */
+/* Like fdopen().  Create a ui_file from a previously opened FILE.  */
 
 struct ui_file *
 stdio_fileopen (FILE *file)
This page took 0.026463 seconds and 4 git commands to generate.