/* Remote target communications for serial-line targets in custom GDB protocol
- Copyright 1988, 91, 92, 93, 94, 95, 96, 97, 98, 1999
- Free Software Foundation, Inc.
+ Copyright 1988, 1991-2000 Free Software Foundation, Inc.
This file is part of GDB.
#include "bfd.h"
#include "symfile.h"
#include "target.h"
-#include "wait.h"
+#include "gdb_wait.h"
/*#include "terminal.h" */
#include "gdbcmd.h"
#include "objfiles.h"
/* Prototypes for local functions */
static void cleanup_sigint_signal_handler (void *dummy);
static void initialize_sigint_signal_handler (void);
+static int getpkt_sane (char *buf, long sizeof_buf, int forever);
static void handle_remote_sigint PARAMS ((int));
static void handle_remote_sigint_twice PARAMS ((int));
static struct target_ops extended_async_remote_ops;
-/* This was 5 seconds, which is a long time to sit and wait.
- Unless this is going though some terminal server or multiplexer or
- other form of hairy serial connection, I would think 2 seconds would
- be plenty. */
-
-/* Changed to allow option to set timeout value.
- was static int remote_timeout = 2; */
-extern int remote_timeout;
-
/* FIXME: cagney/1999-09-23: Even though getpkt was called with
``forever'' still use the normal timeout mechanism. This is
currently used by the ASYNC code to guarentee that target reads
if (!in_thread_list (currthread))
{
add_thread (currthread);
+#ifdef UI_OUT
+ ui_out_text (uiout, "[New ");
+ ui_out_text (uiout, target_pid_to_str (currthread));
+ ui_out_text (uiout, "]\n");
+#else
printf_filtered ("[New %s]\n", target_pid_to_str (currthread));
+#endif
}
}
{
if (name == 0)
error ("To open a remote debug connection, you need to specify what\n\
-serial device is attached to the remote system (e.g. /dev/ttya).");
+serial device is attached to the remote system\n\
+(e.g. /dev/ttyS0, /dev/ttya, COM1, etc.).");
/* See FIXME above */
wait_forever_enabled_p = 1;
{
if (name == 0)
error ("To open a remote debug connection, you need to specify what\n\
-serial device is attached to the remote system (e.g. /dev/ttya).");
+serial device is attached to the remote system\n\
+(e.g. /dev/ttyS0, /dev/ttya, COM1, etc.).");
target_preopen (from_tty);
remote_send (buf, PBUFSIZ);
/* Unregister the file descriptor from the event loop. */
- if (SERIAL_IS_ASYNC_P (remote_desc))
+ if (target_is_async_p ())
SERIAL_ASYNC (remote_desc, NULL, 0);
pop_target ();
/* FIXME: ezannoni 1999-09-28: We may need to move this out of here
into infcmd.c in order to allow inferior function calls to work
NOT asynchronously. */
- if (event_loop_p && SERIAL_CAN_ASYNC_P (remote_desc))
+ if (event_loop_p && target_can_async_p ())
target_async (inferior_event_handler, 0);
/* Tell the world that the target is now executing. */
/* FIXME: cagney/1999-09-23: Is it the targets responsibility to set
this? Instead, should the client of target just assume (for
async targets) that the target is going to start executing? Is
this information already found in the continuation block? */
- if (SERIAL_IS_ASYNC_P (remote_desc))
+ if (target_is_async_p ())
target_executing = 1;
putpkt (buf);
}
{
unsigned char *p;
- if (!SERIAL_IS_ASYNC_P (remote_desc))
+ if (!target_is_async_p ())
ofunc = signal (SIGINT, remote_interrupt);
/* FIXME: cagney/1999-09-27: If we're in async mode we should
_never_ wait for ever -> test on target_is_async_p().
However, before we do that we need to ensure that the caller
knows how to take the target into/out of async mode. */
getpkt (buf, PBUFSIZ, wait_forever_enabled_p);
- if (!SERIAL_IS_ASYNC_P (remote_desc))
+ if (!target_is_async_p ())
signal (SIGINT, ofunc);
/* This is a hook for when we need to do something (perhaps the
switch (ch)
{
case '+':
+ case '-':
case SERIAL_TIMEOUT:
case '$':
if (started_error_output)
if (remote_debug)
fprintf_unfiltered (gdb_stdlog, "Ack\n");
return 1;
+ case '-':
+ if (remote_debug)
+ fprintf_unfiltered (gdb_stdlog, "Nak\n");
case SERIAL_TIMEOUT:
tcount++;
if (tcount > 3)
store it in BUF. If FOREVER, wait forever rather than timing out;
this is used (in synchronous mode) to wait for a target that is is
executing user code to stop. */
-
+/* FIXME: ezannoni 2000-02-01 this wrapper is necessary so that we
+ don't have to change all the calls to getpkt to deal with the
+ return value, because at the moment I don't know what the right
+ thing to do it for those. */
void
getpkt (char *buf,
long sizeof_buf,
int forever)
+{
+ int timed_out;
+
+ timed_out = getpkt_sane (buf, sizeof_buf, forever);
+}
+
+
+/* Read a packet from the remote machine, with error checking, and
+ store it in BUF. If FOREVER, wait forever rather than timing out;
+ this is used (in synchronous mode) to wait for a target that is is
+ executing user code to stop. If FOREVER == 0, this function is
+ allowed to time out gracefully and return an indication of this to
+ the caller. */
+int
+getpkt_sane (char *buf,
+ long sizeof_buf,
+ int forever)
{
int c;
int tries;
fprintf_unfiltered (gdb_stdlog, "\n");
}
SERIAL_WRITE (remote_desc, "+", 1);
- return;
+ return 0;
}
/* Try the whole thing again. */
printf_unfiltered ("Ignoring packet error, continuing...\n");
SERIAL_WRITE (remote_desc, "+", 1);
+ return 1;
}
\f
static void
remote_async_kill ()
{
/* Unregister the file descriptor from the event loop. */
- if (SERIAL_IS_ASYNC_P (remote_desc))
+ if (target_is_async_p ())
SERIAL_ASYNC (remote_desc, NULL, 0);
/* For some mysterious reason, wait_for_inferior calls kill instead of
static void
remote_rcmd (char *command,
- struct gdb_file *outbuf)
+ struct ui_file *outbuf)
{
int i;
char *buf = alloca (PBUFSIZ);
remote_ops.to_longname = "Remote serial target in gdb-specific protocol";
remote_ops.to_doc =
"Use a remote computer via a serial line, using a gdb-specific protocol.\n\
-Specify the serial device it is connected to (e.g. /dev/ttya).";
+Specify the serial device it is connected to\n\
+(e.g. /dev/ttyS0, /dev/ttya, COM1, etc.).";
remote_ops.to_open = remote_open;
remote_ops.to_close = remote_close;
remote_ops.to_detach = remote_detach;
remote_can_async_p (void)
{
/* We're async whenever the serial device is. */
- return SERIAL_CAN_ASYNC_P (remote_desc);
+ return (current_target.to_async_mask_value) && SERIAL_CAN_ASYNC_P (remote_desc);
}
static int
remote_is_async_p (void)
{
/* We're async whenever the serial device is. */
- return SERIAL_IS_ASYNC_P (remote_desc);
+ return (current_target.to_async_mask_value) && SERIAL_IS_ASYNC_P (remote_desc);
}
/* Pass the SERIAL event on and up to the client. One day this code
static void
remote_async (void (*callback) (enum inferior_event_type event_type, void *context), void *context)
{
+ if (current_target.to_async_mask_value == 0)
+ internal_error ("Calling remote_async when async is masked");
+
if (callback != NULL)
{
SERIAL_ASYNC (remote_desc, remote_async_serial_handler, NULL);
remote_async_ops.to_can_async_p = remote_can_async_p;
remote_async_ops.to_is_async_p = remote_is_async_p;
remote_async_ops.to_async = remote_async;
+ remote_async_ops.to_async_mask_value = 1;
remote_async_ops.to_magic = OPS_MAGIC;
}
terminating `#' character and checksum.",
&maintenancelist);
- add_show_from_set
- (add_set_cmd ("remotetimeout", no_class,
- var_integer, (char *) &remote_timeout,
- "Set timeout value for remote read.\n",
- &setlist),
- &showlist);
-
add_show_from_set
(add_set_cmd ("remotebreak", no_class,
var_boolean, (char *) &remote_break,