aboutsummaryrefslogtreecommitdiff
path: root/gdb/gdbserver/remote-utils.c
diff options
context:
space:
mode:
authorDoug Evans <dje@google.com>2011-12-16 19:06:38 +0000
committerDoug Evans <dje@google.com>2011-12-16 19:06:38 +0000
commite0f9f062204827dd5f8a01ab9252ec29273cd3b0 (patch)
treeb59a5c9d50f4d48b63a75b4d1a63213eee7c7c1d /gdb/gdbserver/remote-utils.c
parente77616d77a34e00c99d803b2324e17ece340ac5e (diff)
downloadgdb-e0f9f062204827dd5f8a01ab9252ec29273cd3b0.zip
gdb-e0f9f062204827dd5f8a01ab9252ec29273cd3b0.tar.gz
gdb-e0f9f062204827dd5f8a01ab9252ec29273cd3b0.tar.bz2
* NEWS: Add entry for stdio gdbserver.
gdbserver/ * linux-low.c (linux_create_inferior): If stdio connection, redirect stdin from /dev/null, stdout to stderr. * remote-utils.c (remote_is_stdio): New static global. (remote_connection_is_stdio): New function. (remote_prepare): Handle stdio connection. (remote_open): Ditto. (remote_close): Don't close stdin for stdio connections. (read_prim,write_prim): New functions. Replace all calls to read/write to these. * server.c (main): Watch for "-" argument. Move call to remote_prepare before start_inferior. * server.h (STDIO_CONNECTION_NAME): New macro. (remote_connection_is_stdio): Declare. doc/ * gdb.texinfo (Server): Document -/stdio argument to gdbserver. testsuite/ * lib/gdbserver-support.exp (gdb_target_cmd): Recognize stdio gdbserver output. (gdbserver_default_get_remote_address): New function. (gdbserver_start): Call gdb,get_remote_address to compute argument to "target remote" command.
Diffstat (limited to 'gdb/gdbserver/remote-utils.c')
-rw-r--r--gdb/gdbserver/remote-utils.c85
1 files changed, 74 insertions, 11 deletions
diff --git a/gdb/gdbserver/remote-utils.c b/gdb/gdbserver/remote-utils.c
index 86a7bcf..cdde209 100644
--- a/gdb/gdbserver/remote-utils.c
+++ b/gdb/gdbserver/remote-utils.c
@@ -107,6 +107,8 @@ struct sym_cache
int remote_debug = 0;
struct ui_file *gdb_stdlog;
+static int remote_is_stdio = 0;
+
static gdb_fildes_t remote_desc = INVALID_DESCRIPTOR;
static gdb_fildes_t listen_desc = INVALID_DESCRIPTOR;
@@ -130,6 +132,14 @@ gdb_connected (void)
return remote_desc != INVALID_DESCRIPTOR;
}
+/* Return true if the remote connection is over stdio. */
+
+int
+remote_connection_is_stdio (void)
+{
+ return remote_is_stdio;
+}
+
static void
enable_async_notification (int fd)
{
@@ -222,6 +232,17 @@ remote_prepare (char *name)
socklen_t tmp;
char *port_end;
+ remote_is_stdio = 0;
+ if (strcmp (name, STDIO_CONNECTION_NAME) == 0)
+ {
+ /* We need to record fact that we're using stdio sooner than the
+ call to remote_open so start_inferior knows the connection is
+ via stdio. */
+ remote_is_stdio = 1;
+ transport_is_reliable = 1;
+ return;
+ }
+
port_str = strchr (name, ':');
if (port_str == NULL)
{
@@ -272,11 +293,27 @@ remote_open (char *name)
char *port_str;
port_str = strchr (name, ':');
+#ifdef USE_WIN32API
if (port_str == NULL)
+ error ("Only <host>:<port> is supported on this platform.");
+#endif
+
+ if (strcmp (name, STDIO_CONNECTION_NAME) == 0)
+ {
+ fprintf (stderr, "Remote debugging using stdio\n");
+
+ /* Use stdin as the handle of the connection.
+ We only select on reads, for example. */
+ remote_desc = fileno (stdin);
+
+ enable_async_notification (remote_desc);
+
+ /* Register the event loop handler. */
+ add_file_handler (remote_desc, handle_serial_event, NULL);
+ }
+#ifndef USE_WIN32API
+ else if (port_str == NULL)
{
-#ifdef USE_WIN32API
- error ("Only <host>:<port> is supported on this platform.");
-#else
struct stat statbuf;
if (stat (name, &statbuf) == 0
@@ -341,8 +378,8 @@ remote_open (char *name)
/* Register the event loop handler. */
add_file_handler (remote_desc, handle_serial_event, NULL);
-#endif /* USE_WIN32API */
}
+#endif /* USE_WIN32API */
else
{
int port;
@@ -372,7 +409,8 @@ remote_close (void)
#ifdef USE_WIN32API
closesocket (remote_desc);
#else
- close (remote_desc);
+ if (! remote_connection_is_stdio ())
+ close (remote_desc);
#endif
remote_desc = INVALID_DESCRIPTOR;
@@ -731,6 +769,32 @@ read_ptid (char *buf, char **obuf)
return ptid_build (pid, tid, 0);
}
+/* Write COUNT bytes in BUF to the client.
+ The result is the number of bytes written or -1 if error.
+ This may return less than COUNT. */
+
+static int
+write_prim (const void *buf, int count)
+{
+ if (remote_connection_is_stdio ())
+ return write (fileno (stdout), buf, count);
+ else
+ return write (remote_desc, buf, count);
+}
+
+/* Read COUNT bytes from the client and store in BUF.
+ The result is the number of bytes read or -1 if error.
+ This may return less than COUNT. */
+
+static int
+read_prim (void *buf, int count)
+{
+ if (remote_connection_is_stdio ())
+ return read (fileno (stdin), buf, count);
+ else
+ return read (remote_desc, buf, count);
+}
+
/* Send a packet to the remote machine, with error checking.
The data of the packet is in BUF, and the length of the
packet is in CNT. Returns >= 0 on success, -1 otherwise. */
@@ -768,7 +832,7 @@ putpkt_binary_1 (char *buf, int cnt, int is_notif)
do
{
- if (write (remote_desc, buf2, p - buf2) != p - buf2)
+ if (write_prim (buf2, p - buf2) != p - buf2)
{
perror ("putpkt(write)");
free (buf2);
@@ -863,7 +927,7 @@ input_interrupt (int unused)
int cc;
char c = 0;
- cc = read (remote_desc, &c, 1);
+ cc = read_prim (&c, 1);
if (cc != 1 || c != '\003' || current_inferior == NULL)
{
@@ -991,8 +1055,7 @@ readchar (void)
if (readchar_bufcnt == 0)
{
- readchar_bufcnt = read (remote_desc, readchar_buf,
- sizeof (readchar_buf));
+ readchar_bufcnt = read_prim (readchar_buf, sizeof (readchar_buf));
if (readchar_bufcnt <= 0)
{
@@ -1114,7 +1177,7 @@ getpkt (char *buf)
fprintf (stderr, "Bad checksum, sentsum=0x%x, csum=0x%x, buf=%s\n",
(c1 << 4) + c2, csum, buf);
- if (write (remote_desc, "-", 1) != 1)
+ if (write_prim ("-", 1) != 1)
return -1;
}
@@ -1126,7 +1189,7 @@ getpkt (char *buf)
fflush (stderr);
}
- if (write (remote_desc, "+", 1) != 1)
+ if (write_prim ("+", 1) != 1)
return -1;
if (remote_debug)