198944Sobrien/* Handling of inferior events for the event loop for GDB, the GNU debugger.
298944Sobrien   Copyright 1999 Free Software Foundation, Inc.
398944Sobrien   Written by Elena Zannoni <ezannoni@cygnus.com> of Cygnus Solutions.
498944Sobrien
598944Sobrien   This file is part of GDB.
698944Sobrien
798944Sobrien   This program is free software; you can redistribute it and/or modify
898944Sobrien   it under the terms of the GNU General Public License as published by
998944Sobrien   the Free Software Foundation; either version 2 of the License, or
1098944Sobrien   (at your option) any later version.
1198944Sobrien
1298944Sobrien   This program is distributed in the hope that it will be useful,
1398944Sobrien   but WITHOUT ANY WARRANTY; without even the implied warranty of
1498944Sobrien   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1598944Sobrien   GNU General Public License for more details.
1698944Sobrien
1798944Sobrien   You should have received a copy of the GNU General Public License
1898944Sobrien   along with this program; if not, write to the Free Software
1998944Sobrien   Foundation, Inc., 59 Temple Place - Suite 330,
2098944Sobrien   Boston, MA 02111-1307, USA. */
2198944Sobrien
2298944Sobrien#include "defs.h"
2398944Sobrien#include "inferior.h"		/* For fetch_inferior_event. */
2498944Sobrien#include "target.h"             /* For enum inferior_event_type. */
2598944Sobrien#include "event-loop.h"
2698944Sobrien#include "event-top.h"
2798944Sobrien#include "inf-loop.h"
2898944Sobrien#include "remote.h"
2998944Sobrien
3098944Sobrienstatic int fetch_inferior_event_wrapper (gdb_client_data client_data);
3198944Sobrienstatic void complete_execution (void);
3298944Sobrien
3398944Sobrienvoid
3498944Sobrieninferior_event_handler_wrapper (gdb_client_data client_data)
3598944Sobrien{
3698944Sobrien  inferior_event_handler (INF_QUIT_REQ, client_data);
3798944Sobrien}
3898944Sobrien
3998944Sobrien/* General function to handle events in the inferior. So far it just
4098944Sobrien   takes care of detecting errors reported by select() or poll(),
4198944Sobrien   otherwise it assumes that all is OK, and goes on reading data from
4298944Sobrien   the fd. This however may not always be what we want to do. */
4398944Sobrienvoid
4498944Sobrieninferior_event_handler (enum inferior_event_type event_type,
4598944Sobrien			gdb_client_data client_data)
4698944Sobrien{
4798944Sobrien  switch (event_type)
4898944Sobrien    {
4998944Sobrien    case INF_ERROR:
5098944Sobrien      printf_unfiltered ("error detected from target.\n");
5198944Sobrien      target_async (NULL, 0);
5298944Sobrien      pop_target ();
5398944Sobrien      discard_all_continuations ();
5498944Sobrien      do_exec_error_cleanups (ALL_CLEANUPS);
5598944Sobrien      break;
5698944Sobrien
5798944Sobrien    case INF_REG_EVENT:
5898944Sobrien      /* Use catch errors for now, until the inner layers of
5998944Sobrien	 fetch_inferior_event (i.e. readchar) can return meaningful
6098944Sobrien	 error status.  If an error occurs while getting an event from
6198944Sobrien	 the target, just get rid of the target. */
6298944Sobrien      if (!catch_errors (fetch_inferior_event_wrapper,
6398944Sobrien			 client_data, "", RETURN_MASK_ALL))
6498944Sobrien	{
6598944Sobrien	  target_async (NULL, 0);
6698944Sobrien	  pop_target ();
6798944Sobrien	  discard_all_continuations ();
6898944Sobrien	  do_exec_error_cleanups (ALL_CLEANUPS);
6998944Sobrien	  display_gdb_prompt (0);
7098944Sobrien	}
7198944Sobrien      break;
7298944Sobrien
7398944Sobrien    case INF_EXEC_COMPLETE:
7498944Sobrien      /* Is there anything left to do for the command issued to
7598944Sobrien         complete? */
7698944Sobrien      do_all_continuations ();
7798944Sobrien      /* Reset things after target has stopped for the async commands. */
7898944Sobrien      complete_execution ();
7998944Sobrien      break;
8098944Sobrien
8198944Sobrien    case INF_EXEC_CONTINUE:
8298944Sobrien      /* Is there anything left to do for the command issued to
8398944Sobrien         complete? */
8498944Sobrien      do_all_intermediate_continuations ();
8598944Sobrien      break;
8698944Sobrien
8798944Sobrien    case INF_QUIT_REQ:
8898944Sobrien      /* FIXME: ezannoni 1999-10-04. This call should really be a
8998944Sobrien	 target vector entry, so that it can be used for any kind of
9098944Sobrien	 targets. */
9198944Sobrien      async_remote_interrupt_twice (NULL);
9298944Sobrien      break;
9398944Sobrien
9498944Sobrien    case INF_TIMER:
9598944Sobrien    default:
9698944Sobrien      printf_unfiltered ("Event type not recognized.\n");
9798944Sobrien      break;
9898944Sobrien    }
9998944Sobrien}
10098944Sobrien
10198944Sobrienstatic int
10298944Sobrienfetch_inferior_event_wrapper (gdb_client_data client_data)
10398944Sobrien{
10498944Sobrien  fetch_inferior_event (client_data);
10598944Sobrien  return 1;
10698944Sobrien}
10798944Sobrien
10898944Sobrien/* Reset proper settings after an asynchronous command has finished.
10998944Sobrien   If the execution command was in synchronous mode, register stdin
11098944Sobrien   with the event loop, and reset the prompt. */
11198944Sobrien
11298944Sobrienstatic void
11398944Sobriencomplete_execution (void)
11498944Sobrien{
11598944Sobrien  target_executing = 0;
11698944Sobrien
11798944Sobrien  /* Unregister the inferior from the event loop. This is done so that
11898944Sobrien     when the inferior is not running we don't get distracted by
11998944Sobrien     spurious inferior output. */
12098944Sobrien  target_async (NULL, 0);
12198944Sobrien
12298944Sobrien  if (sync_execution)
12398944Sobrien    {
12498944Sobrien      do_exec_error_cleanups (ALL_CLEANUPS);
12598944Sobrien      display_gdb_prompt (0);
12698944Sobrien    }
12798944Sobrien  else
12898944Sobrien    {
12998944Sobrien      if (exec_done_display_p)
13098944Sobrien	printf_unfiltered ("completed.\n");
13198944Sobrien    }
13298944Sobrien}
133