public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: "Jon Beniston" <jon@beniston.com>
To: <gdb-patches@sourceware.org>
Subject: [PATCH] PR21985: set inferior-tty doesn't work for remote or sim
Date: Mon, 21 Aug 2017 16:20:00 -0000	[thread overview]
Message-ID: <00f001d31a99$7080bd00$51823700$@beniston.com> (raw)

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);
 }



             reply	other threads:[~2017-08-21 16:20 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-08-21 16:20 Jon Beniston [this message]
2017-09-03 16:27 ` Simon Marchi
2017-09-25 15:42   ` Jon Beniston

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='00f001d31a99$7080bd00$51823700$@beniston.com' \
    --to=jon@beniston.com \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).