* exec.c: #include "arch-utils.h"
[deliverable/binutils-gdb.git] / gdb / event-loop.c
index 285cea474417dbc975a48eac5e2099d28938391b..94f07e96e6831280d80e1297b9e78cf338d03948 100644 (file)
@@ -1,12 +1,13 @@
 /* Event loop machinery for GDB, the GNU debugger.
-   Copyright 1999, 2000, 2001 Free Software Foundation, Inc.
+   Copyright (C) 1999, 2000, 2001, 2002, 2005, 2006, 2007, 2008
+   Free Software Foundation, Inc.
    Written by Elena Zannoni <ezannoni@cygnus.com> of Cygnus Solutions.
 
    This file is part of GDB.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA. */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
 
 #include "defs.h"
-#include "top.h"
 #include "event-loop.h"
 #include "event-top.h"
 
@@ -36,6 +34,9 @@
 #include "gdb_string.h"
 #include <errno.h>
 #include <sys/time.h>
+#include "exceptions.h"
+#include "gdb_assert.h"
+#include "gdb_select.h"
 
 typedef struct gdb_event gdb_event;
 typedef void (event_handler_func) (int);
@@ -133,6 +134,11 @@ event_queue;
 
 static unsigned char use_poll = USE_POLL;
 
+#ifdef USE_WIN32API
+#include <windows.h>
+#include <io.h>
+#endif
+
 static struct
   {
     /* Ptr to head of file handler list. */
@@ -211,7 +217,6 @@ static void create_file_handler (int fd, int mask, handler_func * proc, gdb_clie
 static void invoke_async_signal_handler (void);
 static void handle_file_event (int event_file_desc);
 static int gdb_wait_for_event (void);
-static int gdb_do_one_event (void *data);
 static int check_async_ready (void);
 static void async_queue_event (gdb_event * event_ptr, queue_position position);
 static gdb_event *create_file_event (int fd);
@@ -347,7 +352,7 @@ process_event (void)
    can happen if there are no event sources to wait for).  If an error
    occurs catch_errors() which calls this function returns zero. */
 
-static int
+int
 gdb_do_one_event (void *data)
 {
   /* Any events already waiting in the queue? */
@@ -394,15 +399,30 @@ start_event_loop (void)
      longer any event sources registered. */
   while (1)
     {
-      int result = catch_errors (gdb_do_one_event, 0, "", RETURN_MASK_ALL);
-      if (result < 0)
+      int gdb_result;
+
+      gdb_result = catch_errors (gdb_do_one_event, 0, "", RETURN_MASK_ALL);
+      if (gdb_result < 0)
        break;
-      if (result == 0)
+
+      /* If we long-jumped out of do_one_event, we probably
+         didn't get around to resetting the prompt, which leaves
+         readline in a messed-up state.  Reset it here. */
+
+      if (gdb_result == 0)
        {
          /* FIXME: this should really be a call to a hook that is
             interface specific, because interfaces can display the
             prompt in their own way. */
          display_gdb_prompt (0);
+         /* This call looks bizarre, but it is required.  If the user
+            entered a command that caused an error,
+            after_char_processing_hook won't be called from
+            rl_callback_read_char_wrapper.  Using a cleanup there
+            won't work, since we want this function to be called
+            after a new prompt is printed.  */
+         if (after_char_processing_hook)
+           (*after_char_processing_hook) ();
          /* Maybe better to set a flag to be checked somewhere as to
             whether display the prompt or not. */
        }
@@ -438,7 +458,7 @@ add_file_handler (int fd, handler_func * proc, gdb_client_data client_data)
        use_poll = 0;
 #else
       internal_error (__FILE__, __LINE__,
-                     "use_poll without HAVE_POLL");
+                     _("use_poll without HAVE_POLL"));
 #endif /* HAVE_POLL */
     }
   if (use_poll)
@@ -447,7 +467,7 @@ add_file_handler (int fd, handler_func * proc, gdb_client_data client_data)
       create_file_handler (fd, POLLIN, proc, client_data);
 #else
       internal_error (__FILE__, __LINE__,
-                     "use_poll without HAVE_POLL");
+                     _("use_poll without HAVE_POLL"));
 #endif
     }
   else
@@ -487,51 +507,52 @@ create_file_handler (int fd, int mask, handler_func * proc, gdb_client_data clie
       file_ptr->ready_mask = 0;
       file_ptr->next_file = gdb_notifier.first_file_handler;
       gdb_notifier.first_file_handler = file_ptr;
-    }
-  file_ptr->proc = proc;
-  file_ptr->client_data = client_data;
-  file_ptr->mask = mask;
 
-  if (use_poll)
-    {
+      if (use_poll)
+       {
 #ifdef HAVE_POLL
-      gdb_notifier.num_fds++;
-      if (gdb_notifier.poll_fds)
-       gdb_notifier.poll_fds =
-         (struct pollfd *) xrealloc (gdb_notifier.poll_fds,
-                                     (gdb_notifier.num_fds
-                                      * sizeof (struct pollfd)));
-      else
-       gdb_notifier.poll_fds =
-         (struct pollfd *) xmalloc (sizeof (struct pollfd));
-      (gdb_notifier.poll_fds + gdb_notifier.num_fds - 1)->fd = fd;
-      (gdb_notifier.poll_fds + gdb_notifier.num_fds - 1)->events = mask;
-      (gdb_notifier.poll_fds + gdb_notifier.num_fds - 1)->revents = 0;
+         gdb_notifier.num_fds++;
+         if (gdb_notifier.poll_fds)
+           gdb_notifier.poll_fds =
+             (struct pollfd *) xrealloc (gdb_notifier.poll_fds,
+                                         (gdb_notifier.num_fds
+                                          * sizeof (struct pollfd)));
+         else
+           gdb_notifier.poll_fds =
+             (struct pollfd *) xmalloc (sizeof (struct pollfd));
+         (gdb_notifier.poll_fds + gdb_notifier.num_fds - 1)->fd = fd;
+         (gdb_notifier.poll_fds + gdb_notifier.num_fds - 1)->events = mask;
+         (gdb_notifier.poll_fds + gdb_notifier.num_fds - 1)->revents = 0;
 #else
-      internal_error (__FILE__, __LINE__,
-                     "use_poll without HAVE_POLL");
+         internal_error (__FILE__, __LINE__,
+                         _("use_poll without HAVE_POLL"));
 #endif /* HAVE_POLL */
-    }
-  else
-    {
-      if (mask & GDB_READABLE)
-       FD_SET (fd, &gdb_notifier.check_masks[0]);
+       }
       else
-       FD_CLR (fd, &gdb_notifier.check_masks[0]);
+       {
+         if (mask & GDB_READABLE)
+           FD_SET (fd, &gdb_notifier.check_masks[0]);
+         else
+           FD_CLR (fd, &gdb_notifier.check_masks[0]);
 
-      if (mask & GDB_WRITABLE)
-       FD_SET (fd, &gdb_notifier.check_masks[1]);
-      else
-       FD_CLR (fd, &gdb_notifier.check_masks[1]);
+         if (mask & GDB_WRITABLE)
+           FD_SET (fd, &gdb_notifier.check_masks[1]);
+         else
+           FD_CLR (fd, &gdb_notifier.check_masks[1]);
 
-      if (mask & GDB_EXCEPTION)
-       FD_SET (fd, &gdb_notifier.check_masks[2]);
-      else
-       FD_CLR (fd, &gdb_notifier.check_masks[2]);
+         if (mask & GDB_EXCEPTION)
+           FD_SET (fd, &gdb_notifier.check_masks[2]);
+         else
+           FD_CLR (fd, &gdb_notifier.check_masks[2]);
 
-      if (gdb_notifier.num_fds <= fd)
-       gdb_notifier.num_fds = fd + 1;
+         if (gdb_notifier.num_fds <= fd)
+           gdb_notifier.num_fds = fd + 1;
+       }
     }
+
+  file_ptr->proc = proc;
+  file_ptr->client_data = client_data;
+  file_ptr->mask = mask;
 }
 
 /* Remove the file descriptor FD from the list of monitored fd's: 
@@ -582,7 +603,7 @@ delete_file_handler (int fd)
       gdb_notifier.num_fds--;
 #else
       internal_error (__FILE__, __LINE__,
-                     "use_poll without HAVE_POLL");
+                     _("use_poll without HAVE_POLL"));
 #endif /* HAVE_POLL */
     }
   else
@@ -673,25 +694,25 @@ handle_file_event (int event_file_desc)
                  /* Work in progress. We may need to tell somebody what
                     kind of error we had. */
                  if (error_mask_returned & POLLHUP)
-                   printf_unfiltered ("Hangup detected on fd %d\n", file_ptr->fd);
+                   printf_unfiltered (_("Hangup detected on fd %d\n"), file_ptr->fd);
                  if (error_mask_returned & POLLERR)
-                   printf_unfiltered ("Error detected on fd %d\n", file_ptr->fd);
+                   printf_unfiltered (_("Error detected on fd %d\n"), file_ptr->fd);
                  if (error_mask_returned & POLLNVAL)
-                   printf_unfiltered ("Invalid or non-`poll'able fd %d\n", file_ptr->fd);
+                   printf_unfiltered (_("Invalid or non-`poll'able fd %d\n"), file_ptr->fd);
                  file_ptr->error = 1;
                }
              else
                file_ptr->error = 0;
 #else
              internal_error (__FILE__, __LINE__,
-                             "use_poll without HAVE_POLL");
+                             _("use_poll without HAVE_POLL"));
 #endif /* HAVE_POLL */
            }
          else
            {
              if (file_ptr->ready_mask & GDB_EXCEPTION)
                {
-                 printf_unfiltered ("Exception condition detected on fd %d\n", file_ptr->fd);
+                 printf_unfiltered (_("Exception condition detected on fd %d\n"), file_ptr->fd);
                  file_ptr->error = 1;
                }
              else
@@ -743,10 +764,10 @@ gdb_wait_for_event (void)
       /* Don't print anything if we get out of poll because of a
          signal. */
       if (num_found == -1 && errno != EINTR)
-       perror_with_name ("Poll");
+       perror_with_name (("poll"));
 #else
       internal_error (__FILE__, __LINE__,
-                     "use_poll without HAVE_POLL");
+                     _("use_poll without HAVE_POLL"));
 #endif /* HAVE_POLL */
     }
   else
@@ -754,12 +775,12 @@ gdb_wait_for_event (void)
       gdb_notifier.ready_masks[0] = gdb_notifier.check_masks[0];
       gdb_notifier.ready_masks[1] = gdb_notifier.check_masks[1];
       gdb_notifier.ready_masks[2] = gdb_notifier.check_masks[2];
-      num_found = select (gdb_notifier.num_fds,
-                         &gdb_notifier.ready_masks[0],
-                         &gdb_notifier.ready_masks[1],
-                         &gdb_notifier.ready_masks[2],
-                         gdb_notifier.timeout_valid
-                         ? &gdb_notifier.select_timeout : NULL);
+      num_found = gdb_select (gdb_notifier.num_fds,
+                             &gdb_notifier.ready_masks[0],
+                             &gdb_notifier.ready_masks[1],
+                             &gdb_notifier.ready_masks[2],
+                             gdb_notifier.timeout_valid
+                             ? &gdb_notifier.select_timeout : NULL);
 
       /* Clear the masks after an error from select. */
       if (num_found == -1)
@@ -769,7 +790,7 @@ gdb_wait_for_event (void)
          FD_ZERO (&gdb_notifier.ready_masks[2]);
          /* Dont print anything is we got a signal, let gdb handle it. */
          if (errno != EINTR)
-           perror_with_name ("Select");
+           perror_with_name (("select"));
        }
     }
 
@@ -802,13 +823,12 @@ gdb_wait_for_event (void)
                  file_event_ptr = create_file_event (file_ptr->fd);
                  async_queue_event (file_event_ptr, TAIL);
                }
+             file_ptr->ready_mask = (gdb_notifier.poll_fds + i)->revents;
            }
-
-         file_ptr->ready_mask = (gdb_notifier.poll_fds + i)->revents;
        }
 #else
       internal_error (__FILE__, __LINE__,
-                     "use_poll without HAVE_POLL");
+                     _("use_poll without HAVE_POLL"));
 #endif /* HAVE_POLL */
     }
   else
@@ -928,7 +948,7 @@ delete_async_signal_handler (async_signal_handler ** async_handler_ptr)
   else
     {
       prev_ptr = sighandler_list.first_handler;
-      while (prev_ptr->next_handler != (*async_handler_ptr) && prev_ptr)
+      while (prev_ptr && prev_ptr->next_handler != (*async_handler_ptr))
        prev_ptr = prev_ptr->next_handler;
       prev_ptr->next_handler = (*async_handler_ptr)->next_handler;
       if (sighandler_list.last_handler == (*async_handler_ptr))
@@ -1129,7 +1149,7 @@ poll_timers (void)
          gdb_notifier.poll_timeout = delta.tv_sec * 1000;
 #else
          internal_error (__FILE__, __LINE__,
-                         "use_poll without HAVE_POLL");
+                         _("use_poll without HAVE_POLL"));
 #endif /* HAVE_POLL */
        }
       else
This page took 0.043977 seconds and 4 git commands to generate.