/* 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"
#include "gdb_string.h"
#include <errno.h>
#include <sys/time.h>
-
-/* Type of the mask arguments to select. */
-
-#ifndef HAVE_POLL
-#ifdef NO_FD_SET
-/* All this stuff below is not required if select is used as God(tm)
- intended, with the FD_* macros. Are there any implementations of
- select which don't have FD_SET and other standard FD_* macros? I
- don't think there are, but if I'm wrong, we need to catch them. */
-#error FD_SET must be defined if select function is to be used!
-
-#ifndef _AIX
-typedef long fd_mask;
-#endif
-#if defined(_IBMR2)
-#define SELECT_MASK void
-#else
-#define SELECT_MASK int
-#endif /* !_IBMR2 */
-
-/* Define "NBBY" (number of bits per byte) if it's not already defined. */
-
-#ifndef NBBY
-#define NBBY 8
-#endif
-
-/* Define the number of fd_masks in an fd_set */
-
-#ifndef FD_SETSIZE
-#ifdef OPEN_MAX
-#define FD_SETSIZE OPEN_MAX
-#else
-#define FD_SETSIZE 256
-#endif
-#endif
-#if !defined(howmany)
-#define howmany(x, y) (((x)+((y)-1))/(y))
-#endif
-#ifndef NFDBITS
-#define NFDBITS NBBY*sizeof(fd_mask)
-#endif
-#define MASK_SIZE howmany(FD_SETSIZE, NFDBITS)
-
-#endif /* NO_FD_SET */
-#endif /* !HAVE_POLL */
-
+#include "exceptions.h"
+#include "gdb_assert.h"
+#include "gdb_select.h"
typedef struct gdb_event gdb_event;
typedef void (event_handler_func) (int);
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. */
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);
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? */
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. */
}
use_poll = 0;
#else
internal_error (__FILE__, __LINE__,
- "use_poll without HAVE_POLL");
+ _("use_poll without HAVE_POLL"));
#endif /* HAVE_POLL */
}
if (use_poll)
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
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 *) realloc (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:
gdb_notifier.num_fds--;
#else
internal_error (__FILE__, __LINE__,
- "use_poll without HAVE_POLL");
+ _("use_poll without HAVE_POLL"));
#endif /* HAVE_POLL */
}
else
/* 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
/* 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
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)
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"));
}
}
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
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))
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