xref: /openbsd-src/gnu/usr.bin/binutils/gdb/inf-loop.c (revision b725ae7711052a2233e31a66fefb8a752c388d7a)
1*b725ae77Skettenis /* Handling of inferior events for the event loop for GDB, the GNU debugger.
2*b725ae77Skettenis    Copyright 1999 Free Software Foundation, Inc.
3*b725ae77Skettenis    Written by Elena Zannoni <ezannoni@cygnus.com> of Cygnus Solutions.
4*b725ae77Skettenis 
5*b725ae77Skettenis    This file is part of GDB.
6*b725ae77Skettenis 
7*b725ae77Skettenis    This program is free software; you can redistribute it and/or modify
8*b725ae77Skettenis    it under the terms of the GNU General Public License as published by
9*b725ae77Skettenis    the Free Software Foundation; either version 2 of the License, or
10*b725ae77Skettenis    (at your option) any later version.
11*b725ae77Skettenis 
12*b725ae77Skettenis    This program is distributed in the hope that it will be useful,
13*b725ae77Skettenis    but WITHOUT ANY WARRANTY; without even the implied warranty of
14*b725ae77Skettenis    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15*b725ae77Skettenis    GNU General Public License for more details.
16*b725ae77Skettenis 
17*b725ae77Skettenis    You should have received a copy of the GNU General Public License
18*b725ae77Skettenis    along with this program; if not, write to the Free Software
19*b725ae77Skettenis    Foundation, Inc., 59 Temple Place - Suite 330,
20*b725ae77Skettenis    Boston, MA 02111-1307, USA. */
21*b725ae77Skettenis 
22*b725ae77Skettenis #include "defs.h"
23*b725ae77Skettenis #include "inferior.h"		/* For fetch_inferior_event. */
24*b725ae77Skettenis #include "target.h"             /* For enum inferior_event_type. */
25*b725ae77Skettenis #include "event-loop.h"
26*b725ae77Skettenis #include "event-top.h"
27*b725ae77Skettenis #include "inf-loop.h"
28*b725ae77Skettenis #include "remote.h"
29*b725ae77Skettenis 
30*b725ae77Skettenis static int fetch_inferior_event_wrapper (gdb_client_data client_data);
31*b725ae77Skettenis static void complete_execution (void);
32*b725ae77Skettenis 
33*b725ae77Skettenis void
inferior_event_handler_wrapper(gdb_client_data client_data)34*b725ae77Skettenis inferior_event_handler_wrapper (gdb_client_data client_data)
35*b725ae77Skettenis {
36*b725ae77Skettenis   inferior_event_handler (INF_QUIT_REQ, client_data);
37*b725ae77Skettenis }
38*b725ae77Skettenis 
39*b725ae77Skettenis /* General function to handle events in the inferior. So far it just
40*b725ae77Skettenis    takes care of detecting errors reported by select() or poll(),
41*b725ae77Skettenis    otherwise it assumes that all is OK, and goes on reading data from
42*b725ae77Skettenis    the fd. This however may not always be what we want to do. */
43*b725ae77Skettenis void
inferior_event_handler(enum inferior_event_type event_type,gdb_client_data client_data)44*b725ae77Skettenis inferior_event_handler (enum inferior_event_type event_type,
45*b725ae77Skettenis 			gdb_client_data client_data)
46*b725ae77Skettenis {
47*b725ae77Skettenis   switch (event_type)
48*b725ae77Skettenis     {
49*b725ae77Skettenis     case INF_ERROR:
50*b725ae77Skettenis       printf_unfiltered ("error detected from target.\n");
51*b725ae77Skettenis       target_async (NULL, 0);
52*b725ae77Skettenis       pop_target ();
53*b725ae77Skettenis       discard_all_continuations ();
54*b725ae77Skettenis       do_exec_error_cleanups (ALL_CLEANUPS);
55*b725ae77Skettenis       break;
56*b725ae77Skettenis 
57*b725ae77Skettenis     case INF_REG_EVENT:
58*b725ae77Skettenis       /* Use catch errors for now, until the inner layers of
59*b725ae77Skettenis 	 fetch_inferior_event (i.e. readchar) can return meaningful
60*b725ae77Skettenis 	 error status.  If an error occurs while getting an event from
61*b725ae77Skettenis 	 the target, just get rid of the target. */
62*b725ae77Skettenis       if (!catch_errors (fetch_inferior_event_wrapper,
63*b725ae77Skettenis 			 client_data, "", RETURN_MASK_ALL))
64*b725ae77Skettenis 	{
65*b725ae77Skettenis 	  target_async (NULL, 0);
66*b725ae77Skettenis 	  pop_target ();
67*b725ae77Skettenis 	  discard_all_continuations ();
68*b725ae77Skettenis 	  do_exec_error_cleanups (ALL_CLEANUPS);
69*b725ae77Skettenis 	  display_gdb_prompt (0);
70*b725ae77Skettenis 	}
71*b725ae77Skettenis       break;
72*b725ae77Skettenis 
73*b725ae77Skettenis     case INF_EXEC_COMPLETE:
74*b725ae77Skettenis       /* Is there anything left to do for the command issued to
75*b725ae77Skettenis          complete? */
76*b725ae77Skettenis       do_all_continuations ();
77*b725ae77Skettenis       /* Reset things after target has stopped for the async commands. */
78*b725ae77Skettenis       complete_execution ();
79*b725ae77Skettenis       break;
80*b725ae77Skettenis 
81*b725ae77Skettenis     case INF_EXEC_CONTINUE:
82*b725ae77Skettenis       /* Is there anything left to do for the command issued to
83*b725ae77Skettenis          complete? */
84*b725ae77Skettenis       do_all_intermediate_continuations ();
85*b725ae77Skettenis       break;
86*b725ae77Skettenis 
87*b725ae77Skettenis     case INF_QUIT_REQ:
88*b725ae77Skettenis       /* FIXME: ezannoni 1999-10-04. This call should really be a
89*b725ae77Skettenis 	 target vector entry, so that it can be used for any kind of
90*b725ae77Skettenis 	 targets. */
91*b725ae77Skettenis       async_remote_interrupt_twice (NULL);
92*b725ae77Skettenis       break;
93*b725ae77Skettenis 
94*b725ae77Skettenis     case INF_TIMER:
95*b725ae77Skettenis     default:
96*b725ae77Skettenis       printf_unfiltered ("Event type not recognized.\n");
97*b725ae77Skettenis       break;
98*b725ae77Skettenis     }
99*b725ae77Skettenis }
100*b725ae77Skettenis 
101*b725ae77Skettenis static int
fetch_inferior_event_wrapper(gdb_client_data client_data)102*b725ae77Skettenis fetch_inferior_event_wrapper (gdb_client_data client_data)
103*b725ae77Skettenis {
104*b725ae77Skettenis   fetch_inferior_event (client_data);
105*b725ae77Skettenis   return 1;
106*b725ae77Skettenis }
107*b725ae77Skettenis 
108*b725ae77Skettenis /* Reset proper settings after an asynchronous command has finished.
109*b725ae77Skettenis    If the execution command was in synchronous mode, register stdin
110*b725ae77Skettenis    with the event loop, and reset the prompt. */
111*b725ae77Skettenis 
112*b725ae77Skettenis static void
complete_execution(void)113*b725ae77Skettenis complete_execution (void)
114*b725ae77Skettenis {
115*b725ae77Skettenis   target_executing = 0;
116*b725ae77Skettenis 
117*b725ae77Skettenis   /* Unregister the inferior from the event loop. This is done so that
118*b725ae77Skettenis      when the inferior is not running we don't get distracted by
119*b725ae77Skettenis      spurious inferior output. */
120*b725ae77Skettenis   target_async (NULL, 0);
121*b725ae77Skettenis 
122*b725ae77Skettenis   if (sync_execution)
123*b725ae77Skettenis     {
124*b725ae77Skettenis       do_exec_error_cleanups (ALL_CLEANUPS);
125*b725ae77Skettenis       display_gdb_prompt (0);
126*b725ae77Skettenis     }
127*b725ae77Skettenis   else
128*b725ae77Skettenis     {
129*b725ae77Skettenis       if (exec_done_display_p)
130*b725ae77Skettenis 	printf_unfiltered ("completed.\n");
131*b725ae77Skettenis     }
132*b725ae77Skettenis }
133