This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] PR21985: set inferior-tty doesn't work for remote or sim


The set inferior-tty command doesn't appear to work for remote or sim
targets. (That is, remote targets using remote-fileio to have the IO appear
on the debug host).

This is a shame as Eclipse (and potentially other front-ends) use this
command to separate the windows used for target stdio and the gdb console.
Currently, therefore Eclipse isn't supporting remote and sim targets fully.

The attached patch adds support for this command in remote-fileio.c and
remote-sim.c. Reads/writes from/to stdin/stdout are redirected to the tty.

This may not be the ideal way to implement this within GDB, but it does get
it working with Eclipse. I'm not hugely familiar with what ttys should
offer, other than redirect stdio.

Cheers,
Jon


gdb/ChangeLog
	* remote-fileio.c (sim_inferior_data):  New field "tty".
	(gdb_os_read_stdin): New function.
	(get_sim_inferior_data): Initialise tty.
	(sim_inferior_data_cleanup): Close tty if opened.
	(init_callbacks): Add read_stdin callback.
	(gdb_os_write_stdout): Write to tty if opened.
	(gdb_os_write_stderr): Write to tty if opened.
	(gdbsim_create_inferior): Open tty if requested.
	* remote-sim.c (remote_fio_data): New field "tty".
	(remote_fileio_init_fd_map): Open tty if requested.
	(remote_fileio_func_read): read from tty if opened.
	(remote_fileio_func_write): write to tty if opened.
	(remote_fileio_reset): Close tty if opened.

diff --git a/gdb/remote-fileio.c b/gdb/remote-fileio.c
index 252b423bfa..d36d2e7c43 100644
--- a/gdb/remote-fileio.c
+++ b/gdb/remote-fileio.c
@@ -29,6 +29,7 @@
 #include "target.h"
 #include "filenames.h"
 #include "filestuff.h"
+#include "inferior.h"
 
 #include <fcntl.h>
 #include "gdb_sys_time.h"
@@ -40,6 +41,8 @@
 static struct {
   int *fd_map;
   int fd_map_size;
+  int tty;                      /* File descriptor for tty to use if set 
+                                   inferior-tty called.  */
 } remote_fio_data;
 
 #define FIO_FD_INVALID		-1
@@ -52,7 +55,8 @@ static int
 remote_fileio_init_fd_map (void)
 {
   int i;
-
+  const char *term;
+  
   if (!remote_fio_data.fd_map)
     {
       remote_fio_data.fd_map = XNEWVEC (int, 10);
@@ -62,6 +66,15 @@ remote_fileio_init_fd_map (void)
       remote_fio_data.fd_map[2] = FIO_FD_CONSOLE_OUT;
       for (i = 3; i < 10; ++i)
         remote_fio_data.fd_map[i] = FIO_FD_INVALID;
+      term = get_inferior_io_terminal ();
+      if (term != NULL) 
+        {
+          remote_fio_data.tty = open (term, O_RDWR | O_NOCTTY);
+          if (remote_fio_data.tty < 0) 
+            error (_("Unable to open %s as inferior-tty."), term);
+        }
+      else  
+        remote_fio_data.tty = -1;  
     }
   return 3;
 }
@@ -505,52 +518,58 @@ remote_fileio_func_read (char *buf)
 	remote_fileio_badfd ();
 	return;
       case FIO_FD_CONSOLE_IN:
-	{
-	  static char *remaining_buf = NULL;
-	  static int remaining_length = 0;
-
-	  buffer = (gdb_byte *) xmalloc (16384);
-	  if (remaining_buf)
-	    {
-	      if (remaining_length > length)
-		{
-		  memcpy (buffer, remaining_buf, length);
-		  memmove (remaining_buf, remaining_buf + length,
-			   remaining_length - length);
-		  remaining_length -= length;
-		  ret = length;
-		}
-	      else
-		{
-		  memcpy (buffer, remaining_buf, remaining_length);
-		  xfree (remaining_buf);
-		  remaining_buf = NULL;
-		  ret = remaining_length;
-		}
-	    }
-	  else
-	    {
-	      /* Windows (at least XP and Server 2003) has difficulty
-		 with large reads from consoles.  If a handle is
-		 backed by a real console device, overly large reads
-		 from the handle will fail and set errno == ENOMEM.
-		 On a Windows Server 2003 system where I tested,
-		 reading 26608 bytes from the console was OK, but
-		 anything above 26609 bytes would fail.  The limit has
-		 been observed to vary on different systems.  So, we
-		 limit this read to something smaller than that - by a
-		 safe margin, in case the limit depends on system
-		 resources or version.  */
-	      ret = ui_file_read (gdb_stdtargin, (char *) buffer, 16383);
-	      if (ret > 0 && (size_t)ret > length)
-		{
-		  remaining_buf = (char *) xmalloc (ret - length);
-		  remaining_length = ret - length;
-		  memcpy (remaining_buf, buffer + length, remaining_length);
-		  ret = length;
-		}
-	    }
-	}
+        if (remote_fio_data.tty >= 0)
+          { 
+            buffer = (gdb_byte *) xmalloc (length);
+            ret = read (remote_fio_data.tty, buffer, length);
+          }  
+        else
+	  {
+	    static char *remaining_buf = NULL;
+	    static int remaining_length = 0;
+
+	    buffer = (gdb_byte *) xmalloc (16384);
+	    if (remaining_buf)
+	      {
+	        if (remaining_length > length)
+		  {
+		    memcpy (buffer, remaining_buf, length);
+		    memmove (remaining_buf, remaining_buf + length,
+			     remaining_length - length);
+		    remaining_length -= length;
+		    ret = length;
+		  }
+	        else
+		  {
+		    memcpy (buffer, remaining_buf, remaining_length);
+		    xfree (remaining_buf);
+		    remaining_buf = NULL;
+		    ret = remaining_length;
+		  }
+	      }
+	    else
+	      {
+	        /* Windows (at least XP and Server 2003) has difficulty
+		   with large reads from consoles.  If a handle is
+		   backed by a real console device, overly large reads
+		   from the handle will fail and set errno == ENOMEM.
+		   On a Windows Server 2003 system where I tested,
+		   reading 26608 bytes from the console was OK, but
+		   anything above 26609 bytes would fail.  The limit has
+		   been observed to vary on different systems.  So, we
+		   limit this read to something smaller than that - by a
+		   safe margin, in case the limit depends on system
+		   resources or version.  */
+	        ret = ui_file_read (gdb_stdtargin, (char *) buffer, 16383);
+	        if (ret > 0 && (size_t)ret > length)
+		  {
+		    remaining_buf = (char *) xmalloc (ret - length);
+		    remaining_length = ret - length;
+		    memcpy (remaining_buf, buffer + length,
remaining_length);
+		    ret = length;
+		  }
+	      }
+	  }
 	break;
       default:
 	buffer = (gdb_byte *) xmalloc (length);
@@ -639,10 +658,15 @@ remote_fileio_func_write (char *buf)
 	xfree (buffer);
 	return;
       case FIO_FD_CONSOLE_OUT:
-	ui_file_write (target_fd == 1 ? gdb_stdtarg : gdb_stdtargerr,
-		       (char *) buffer, length);
-	gdb_flush (target_fd == 1 ? gdb_stdtarg : gdb_stdtargerr);
-	ret = length;
+        if (remote_fio_data.tty < 0)
+          { 
+	    ui_file_write (target_fd == 1 ? gdb_stdtarg : gdb_stdtargerr,
+		           (char *) buffer, length);
+	    gdb_flush (target_fd == 1 ? gdb_stdtarg : gdb_stdtargerr);

+	    ret = length;
+          } 
+        else
+          ret = write (remote_fio_data.tty, buffer, length);
 	break;
       default:
 	ret = write (fd, buffer, length);
@@ -1160,6 +1184,8 @@ remote_fileio_reset (void)
       xfree (remote_fio_data.fd_map);
       remote_fio_data.fd_map = NULL;
       remote_fio_data.fd_map_size = 0;
+      if (remote_fio_data.tty >= 0)
+        close (remote_fio_data.tty);
     }
 }
 
diff --git a/gdb/remote-sim.c b/gdb/remote-sim.c
index ca824d7985..f9557111c4 100644
--- a/gdb/remote-sim.c
+++ b/gdb/remote-sim.c
@@ -50,6 +50,8 @@ static void init_callbacks (void);
 
 static void end_callbacks (void);
 
+static int gdb_os_read_stdin (host_callback *, char *, int);
+
 static int gdb_os_write_stdout (host_callback *, const char *, int);
 
 static void gdb_os_flush_stdout (host_callback *);
@@ -123,6 +125,9 @@ struct sim_inferior_data {
 
   /* Flag which indicates whether resume should step or not.  */
   int resume_step;
+  
+  /* File descriptor for tty to use if set inferior-tty called.  */
+  int tty;
 };
 
 /* Flag indicating the "open" status of this module.  It's set to 1
@@ -221,6 +226,7 @@ get_sim_inferior_data (struct inferior *inf, int
sim_instance_needed)
       sim_data->gdbsim_desc = sim_desc;
       sim_data->resume_siggnal = GDB_SIGNAL_0;
       sim_data->resume_step = 0;
+      sim_data->tty = -1;
     }
   else if (sim_desc)
     {
@@ -268,6 +274,8 @@ sim_inferior_data_cleanup (struct inferior *inf, void
*data)
 	  sim_close (sim_data->gdbsim_desc, 0);
 	  sim_data->gdbsim_desc = NULL;
 	}
+      if (sim_data->tty >= 0)
+        close (sim_data->tty);  
       xfree (sim_data);
     }
 }
@@ -306,6 +314,7 @@ init_callbacks (void)
     {
       gdb_callback = default_callback;
       gdb_callback.init (&gdb_callback);
+      gdb_callback.read_stdin = gdb_os_read_stdin;
       gdb_callback.write_stdout = gdb_os_write_stdout;
       gdb_callback.flush_stdout = gdb_os_flush_stdout;
       gdb_callback.write_stderr = gdb_os_write_stderr;
@@ -332,15 +341,34 @@ end_callbacks (void)
     }
 }
 
+/* GDB version of os_read_stdin callback.  */
+
+static int
+gdb_os_read_stdin (host_callback *p, char *buf, int len)
+{
+  struct sim_inferior_data *sim_data
+    = get_sim_inferior_data (current_inferior (), SIM_INSTANCE_NEEDED);
+  
+  if (sim_data->tty < 0) 
+    len = ui_file_read (gdb_stdtargin, buf, len);
+  else 
+    len = read (sim_data->tty, buf, len);
+  return len;
+}
+
 /* GDB version of os_write_stdout callback.  */
 
 static int
 gdb_os_write_stdout (host_callback *p, const char *buf, int len)
 {
-  int i;
-  char b[2];
+  struct sim_inferior_data *sim_data
+    = get_sim_inferior_data (current_inferior (), SIM_INSTANCE_NEEDED);
+
+  if (sim_data->tty < 0)
+    ui_file_write (gdb_stdtarg, buf, len);
+  else 
+    len = write (sim_data->tty, buf, len);
 
-  ui_file_write (gdb_stdtarg, buf, len);
   return len;
 }
 
@@ -357,15 +385,22 @@ gdb_os_flush_stdout (host_callback *p)
 static int
 gdb_os_write_stderr (host_callback *p, const char *buf, int len)
 {
+  struct sim_inferior_data *sim_data
+    = get_sim_inferior_data (current_inferior (), SIM_INSTANCE_NEEDED);
   int i;
   char b[2];
 
-  for (i = 0; i < len; i++)
+  if (sim_data->tty < 0)
     {
-      b[0] = buf[i];
-      b[1] = 0;
-      fputs_unfiltered (b, gdb_stdtargerr);
+      for (i = 0; i < len; i++)
+        {
+          b[0] = buf[i];
+          b[1] = 0;
+          fputs_unfiltered (b, gdb_stdtargerr);
+        }
     }
+  else
+    len = write (sim_data->tty, buf, len);    
   return len;
 }
 
@@ -609,6 +644,7 @@ gdbsim_create_inferior (struct target_ops *target, const
char *exec_file,
   int len;
   char *arg_buf;
   const char *args = allargs.c_str ();
+  const char *term;
 
   if (exec_file == 0 || exec_bfd == 0)
     warning (_("No executable file specified."));
@@ -652,6 +688,16 @@ gdbsim_create_inferior (struct target_ops *target,
const char *exec_file,
 
   insert_breakpoints ();	/* Needed to get correct instruction
 				   in cache.  */
+  
+  /* We don't do this in open as Eclispe calls set-inferior-tty after 
+     target-select, but before run.  */
+  term = get_inferior_io_terminal ();
+  if (term != NULL)
+    {
+      sim_data->tty = open (term, O_RDWR | O_NOCTTY);
+      if (sim_data->tty < 0) 
+        error (_("Unable to open %s as inferior-tty."), term);  
+    }
 
   clear_proceed_status (0);
 }




Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]