* NEWS: Add entry for stdio gdbserver.
[external/binutils.git] / gdb / gdbserver / remote-utils.c
index 86a7bcf..cdde209 100644 (file)
@@ -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)