From patchwork Mon Aug 21 16:20:42 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jon Beniston X-Patchwork-Id: 22287 Received: (qmail 105708 invoked by alias); 21 Aug 2017 16:20:49 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 104995 invoked by uid 89); 21 Aug 2017 16:20:48 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-21.2 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_LAZY_DOMAIN_SECURITY, RCVD_IN_DNSWL_NONE, UNSUBSCRIBE_BODY autolearn=ham version=3.3.2 spammy=difficulty, overly, consoles, H*x:14.0 X-HELO: smtprelay.hostedemail.com Received: from smtprelay0024.hostedemail.com (HELO smtprelay.hostedemail.com) (216.40.44.24) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 21 Aug 2017 16:20:46 +0000 Received: from filter.hostedemail.com (clb03-v110.bra.tucows.net [216.40.38.60]) by smtprelay04.hostedemail.com (Postfix) with ESMTP id AF050180A8854 for ; Mon, 21 Aug 2017 16:20:44 +0000 (UTC) X-Session-Marker: 6A62656E6973746F6E40756B322E6E6574 X-Spam-Summary: 2, 0, 0, , d41d8cd98f00b204, jon@beniston.com, :, RULES_HIT:1:10:41:355:379:541:542:960:966:973:982:988:989:1155:1260:1277:1311:1313:1314:1345:1381:1437:1515:1516:1518:1587:1593:1594:1605:1730:1747:1777:1792:1801:2110:2194:2196:2199:2200:2393:2553:2559:2562:2637:2693:3138:3139:3140:3141:3142:3865:3866:3867:3868:3870:3871:3872:3874:4250:4321:4385:4605:5007:6117:6119:6120:7875:7903:8957:9121:9592:9707:10004:10394:10848:11026:11232:11473:11658:11914:12296:12438:12555:12663:12679:12760:13019:13138:13161:13229:13231:13439:14096:14097:14394:21063:21080:21451:21627:30046:30054:30090, 0, RBL:none, CacheIP:none, Bayesian:0.5, 0.5, 0.5, Netcheck:none, DomainCache:0, MSF:not bulk, SPF:, MSBL:0, DNSBL:none, Custom_rules:0:0:0, LFtime:2, LUA_SUMMARY:none X-HE-Tag: spoon32_40890d0042420 X-Filterd-Recvd-Size: 12108 Received: from LoftPC (cpc97974-croy24-2-0-cust112.19-2.cable.virginm.net [77.99.44.113]) (Authenticated sender: jbeniston@uk2.net) by omf06.hostedemail.com (Postfix) with ESMTPA for ; Mon, 21 Aug 2017 16:20:43 +0000 (UTC) From: "Jon Beniston" To: Subject: [PATCH] PR21985: set inferior-tty doesn't work for remote or sim Date: Mon, 21 Aug 2017 17:20:42 +0100 Message-ID: <00f001d31a99$7080bd00$51823700$@beniston.com> MIME-Version: 1.0 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. { @@ -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); } 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 #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)