1*5796c8dcSSimon Schubert /* Generic serial interface routines 2*5796c8dcSSimon Schubert 3*5796c8dcSSimon Schubert Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 4*5796c8dcSSimon Schubert 2002, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. 5*5796c8dcSSimon Schubert 6*5796c8dcSSimon Schubert This file is part of GDB. 7*5796c8dcSSimon Schubert 8*5796c8dcSSimon Schubert This program is free software; you can redistribute it and/or modify 9*5796c8dcSSimon Schubert it under the terms of the GNU General Public License as published by 10*5796c8dcSSimon Schubert the Free Software Foundation; either version 3 of the License, or 11*5796c8dcSSimon Schubert (at your option) any later version. 12*5796c8dcSSimon Schubert 13*5796c8dcSSimon Schubert This program is distributed in the hope that it will be useful, 14*5796c8dcSSimon Schubert but WITHOUT ANY WARRANTY; without even the implied warranty of 15*5796c8dcSSimon Schubert MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16*5796c8dcSSimon Schubert GNU General Public License for more details. 17*5796c8dcSSimon Schubert 18*5796c8dcSSimon Schubert You should have received a copy of the GNU General Public License 19*5796c8dcSSimon Schubert along with this program. If not, see <http://www.gnu.org/licenses/>. */ 20*5796c8dcSSimon Schubert 21*5796c8dcSSimon Schubert #include "defs.h" 22*5796c8dcSSimon Schubert #include <ctype.h> 23*5796c8dcSSimon Schubert #include "serial.h" 24*5796c8dcSSimon Schubert #include "gdb_string.h" 25*5796c8dcSSimon Schubert #include "gdbcmd.h" 26*5796c8dcSSimon Schubert 27*5796c8dcSSimon Schubert extern void _initialize_serial (void); 28*5796c8dcSSimon Schubert 29*5796c8dcSSimon Schubert /* Is serial being debugged? */ 30*5796c8dcSSimon Schubert 31*5796c8dcSSimon Schubert static int global_serial_debug_p; 32*5796c8dcSSimon Schubert 33*5796c8dcSSimon Schubert /* Linked list of serial I/O handlers */ 34*5796c8dcSSimon Schubert 35*5796c8dcSSimon Schubert static struct serial_ops *serial_ops_list = NULL; 36*5796c8dcSSimon Schubert 37*5796c8dcSSimon Schubert /* This is the last serial stream opened. Used by connect command. */ 38*5796c8dcSSimon Schubert 39*5796c8dcSSimon Schubert static struct serial *last_serial_opened = NULL; 40*5796c8dcSSimon Schubert 41*5796c8dcSSimon Schubert /* Pointer to list of scb's. */ 42*5796c8dcSSimon Schubert 43*5796c8dcSSimon Schubert static struct serial *scb_base; 44*5796c8dcSSimon Schubert 45*5796c8dcSSimon Schubert /* Non-NULL gives filename which contains a recording of the remote session, 46*5796c8dcSSimon Schubert suitable for playback by gdbserver. */ 47*5796c8dcSSimon Schubert 48*5796c8dcSSimon Schubert static char *serial_logfile = NULL; 49*5796c8dcSSimon Schubert static struct ui_file *serial_logfp = NULL; 50*5796c8dcSSimon Schubert 51*5796c8dcSSimon Schubert static struct serial_ops *serial_interface_lookup (char *); 52*5796c8dcSSimon Schubert static void serial_logchar (struct ui_file *stream, int ch_type, int ch, int timeout); 53*5796c8dcSSimon Schubert static const char logbase_hex[] = "hex"; 54*5796c8dcSSimon Schubert static const char logbase_octal[] = "octal"; 55*5796c8dcSSimon Schubert static const char logbase_ascii[] = "ascii"; 56*5796c8dcSSimon Schubert static const char *logbase_enums[] = 57*5796c8dcSSimon Schubert {logbase_hex, logbase_octal, logbase_ascii, NULL}; 58*5796c8dcSSimon Schubert static const char *serial_logbase = logbase_ascii; 59*5796c8dcSSimon Schubert 60*5796c8dcSSimon Schubert 61*5796c8dcSSimon Schubert static int serial_current_type = 0; 62*5796c8dcSSimon Schubert 63*5796c8dcSSimon Schubert /* Log char CH of type CHTYPE, with TIMEOUT */ 64*5796c8dcSSimon Schubert 65*5796c8dcSSimon Schubert /* Define bogus char to represent a BREAK. Should be careful to choose a value 66*5796c8dcSSimon Schubert that can't be confused with a normal char, or an error code. */ 67*5796c8dcSSimon Schubert #define SERIAL_BREAK 1235 68*5796c8dcSSimon Schubert 69*5796c8dcSSimon Schubert static void 70*5796c8dcSSimon Schubert serial_logchar (struct ui_file *stream, int ch_type, int ch, int timeout) 71*5796c8dcSSimon Schubert { 72*5796c8dcSSimon Schubert if (ch_type != serial_current_type) 73*5796c8dcSSimon Schubert { 74*5796c8dcSSimon Schubert fprintf_unfiltered (stream, "\n%c ", ch_type); 75*5796c8dcSSimon Schubert serial_current_type = ch_type; 76*5796c8dcSSimon Schubert } 77*5796c8dcSSimon Schubert 78*5796c8dcSSimon Schubert if (serial_logbase != logbase_ascii) 79*5796c8dcSSimon Schubert fputc_unfiltered (' ', stream); 80*5796c8dcSSimon Schubert 81*5796c8dcSSimon Schubert switch (ch) 82*5796c8dcSSimon Schubert { 83*5796c8dcSSimon Schubert case SERIAL_TIMEOUT: 84*5796c8dcSSimon Schubert fprintf_unfiltered (stream, "<Timeout: %d seconds>", timeout); 85*5796c8dcSSimon Schubert return; 86*5796c8dcSSimon Schubert case SERIAL_ERROR: 87*5796c8dcSSimon Schubert fprintf_unfiltered (stream, "<Error: %s>", safe_strerror (errno)); 88*5796c8dcSSimon Schubert return; 89*5796c8dcSSimon Schubert case SERIAL_EOF: 90*5796c8dcSSimon Schubert fputs_unfiltered ("<Eof>", stream); 91*5796c8dcSSimon Schubert return; 92*5796c8dcSSimon Schubert case SERIAL_BREAK: 93*5796c8dcSSimon Schubert fputs_unfiltered ("<Break>", stream); 94*5796c8dcSSimon Schubert return; 95*5796c8dcSSimon Schubert default: 96*5796c8dcSSimon Schubert if (serial_logbase == logbase_hex) 97*5796c8dcSSimon Schubert fprintf_unfiltered (stream, "%02x", ch & 0xff); 98*5796c8dcSSimon Schubert else if (serial_logbase == logbase_octal) 99*5796c8dcSSimon Schubert fprintf_unfiltered (stream, "%03o", ch & 0xff); 100*5796c8dcSSimon Schubert else 101*5796c8dcSSimon Schubert switch (ch) 102*5796c8dcSSimon Schubert { 103*5796c8dcSSimon Schubert case '\\': 104*5796c8dcSSimon Schubert fputs_unfiltered ("\\\\", stream); 105*5796c8dcSSimon Schubert break; 106*5796c8dcSSimon Schubert case '\b': 107*5796c8dcSSimon Schubert fputs_unfiltered ("\\b", stream); 108*5796c8dcSSimon Schubert break; 109*5796c8dcSSimon Schubert case '\f': 110*5796c8dcSSimon Schubert fputs_unfiltered ("\\f", stream); 111*5796c8dcSSimon Schubert break; 112*5796c8dcSSimon Schubert case '\n': 113*5796c8dcSSimon Schubert fputs_unfiltered ("\\n", stream); 114*5796c8dcSSimon Schubert break; 115*5796c8dcSSimon Schubert case '\r': 116*5796c8dcSSimon Schubert fputs_unfiltered ("\\r", stream); 117*5796c8dcSSimon Schubert break; 118*5796c8dcSSimon Schubert case '\t': 119*5796c8dcSSimon Schubert fputs_unfiltered ("\\t", stream); 120*5796c8dcSSimon Schubert break; 121*5796c8dcSSimon Schubert case '\v': 122*5796c8dcSSimon Schubert fputs_unfiltered ("\\v", stream); 123*5796c8dcSSimon Schubert break; 124*5796c8dcSSimon Schubert default: 125*5796c8dcSSimon Schubert fprintf_unfiltered (stream, isprint (ch) ? "%c" : "\\x%02x", ch & 0xFF); 126*5796c8dcSSimon Schubert break; 127*5796c8dcSSimon Schubert } 128*5796c8dcSSimon Schubert } 129*5796c8dcSSimon Schubert } 130*5796c8dcSSimon Schubert 131*5796c8dcSSimon Schubert void 132*5796c8dcSSimon Schubert serial_log_command (const char *cmd) 133*5796c8dcSSimon Schubert { 134*5796c8dcSSimon Schubert if (!serial_logfp) 135*5796c8dcSSimon Schubert return; 136*5796c8dcSSimon Schubert 137*5796c8dcSSimon Schubert serial_current_type = 'c'; 138*5796c8dcSSimon Schubert 139*5796c8dcSSimon Schubert fputs_unfiltered ("\nc ", serial_logfp); 140*5796c8dcSSimon Schubert fputs_unfiltered (cmd, serial_logfp); 141*5796c8dcSSimon Schubert 142*5796c8dcSSimon Schubert /* Make sure that the log file is as up-to-date as possible, 143*5796c8dcSSimon Schubert in case we are getting ready to dump core or something. */ 144*5796c8dcSSimon Schubert gdb_flush (serial_logfp); 145*5796c8dcSSimon Schubert } 146*5796c8dcSSimon Schubert 147*5796c8dcSSimon Schubert 148*5796c8dcSSimon Schubert static struct serial_ops * 149*5796c8dcSSimon Schubert serial_interface_lookup (char *name) 150*5796c8dcSSimon Schubert { 151*5796c8dcSSimon Schubert struct serial_ops *ops; 152*5796c8dcSSimon Schubert 153*5796c8dcSSimon Schubert for (ops = serial_ops_list; ops; ops = ops->next) 154*5796c8dcSSimon Schubert if (strcmp (name, ops->name) == 0) 155*5796c8dcSSimon Schubert return ops; 156*5796c8dcSSimon Schubert 157*5796c8dcSSimon Schubert return NULL; 158*5796c8dcSSimon Schubert } 159*5796c8dcSSimon Schubert 160*5796c8dcSSimon Schubert void 161*5796c8dcSSimon Schubert serial_add_interface (struct serial_ops *optable) 162*5796c8dcSSimon Schubert { 163*5796c8dcSSimon Schubert optable->next = serial_ops_list; 164*5796c8dcSSimon Schubert serial_ops_list = optable; 165*5796c8dcSSimon Schubert } 166*5796c8dcSSimon Schubert 167*5796c8dcSSimon Schubert /* Open up a device or a network socket, depending upon the syntax of NAME. */ 168*5796c8dcSSimon Schubert 169*5796c8dcSSimon Schubert struct serial * 170*5796c8dcSSimon Schubert serial_open (const char *name) 171*5796c8dcSSimon Schubert { 172*5796c8dcSSimon Schubert struct serial *scb; 173*5796c8dcSSimon Schubert struct serial_ops *ops; 174*5796c8dcSSimon Schubert const char *open_name = name; 175*5796c8dcSSimon Schubert 176*5796c8dcSSimon Schubert for (scb = scb_base; scb; scb = scb->next) 177*5796c8dcSSimon Schubert if (scb->name && strcmp (scb->name, name) == 0) 178*5796c8dcSSimon Schubert { 179*5796c8dcSSimon Schubert scb->refcnt++; 180*5796c8dcSSimon Schubert return scb; 181*5796c8dcSSimon Schubert } 182*5796c8dcSSimon Schubert 183*5796c8dcSSimon Schubert if (strcmp (name, "pc") == 0) 184*5796c8dcSSimon Schubert ops = serial_interface_lookup ("pc"); 185*5796c8dcSSimon Schubert else if (strncmp (name, "lpt", 3) == 0) 186*5796c8dcSSimon Schubert ops = serial_interface_lookup ("parallel"); 187*5796c8dcSSimon Schubert else if (strncmp (name, "|", 1) == 0) 188*5796c8dcSSimon Schubert { 189*5796c8dcSSimon Schubert ops = serial_interface_lookup ("pipe"); 190*5796c8dcSSimon Schubert /* Discard ``|'' and any space before the command itself. */ 191*5796c8dcSSimon Schubert ++open_name; 192*5796c8dcSSimon Schubert while (isspace (*open_name)) 193*5796c8dcSSimon Schubert ++open_name; 194*5796c8dcSSimon Schubert } 195*5796c8dcSSimon Schubert /* Check for a colon, suggesting an IP address/port pair. 196*5796c8dcSSimon Schubert Do this *after* checking for all the interesting prefixes. We 197*5796c8dcSSimon Schubert don't want to constrain the syntax of what can follow them. */ 198*5796c8dcSSimon Schubert else if (strchr (name, ':')) 199*5796c8dcSSimon Schubert ops = serial_interface_lookup ("tcp"); 200*5796c8dcSSimon Schubert else 201*5796c8dcSSimon Schubert ops = serial_interface_lookup ("hardwire"); 202*5796c8dcSSimon Schubert 203*5796c8dcSSimon Schubert if (!ops) 204*5796c8dcSSimon Schubert return NULL; 205*5796c8dcSSimon Schubert 206*5796c8dcSSimon Schubert scb = XMALLOC (struct serial); 207*5796c8dcSSimon Schubert 208*5796c8dcSSimon Schubert scb->ops = ops; 209*5796c8dcSSimon Schubert 210*5796c8dcSSimon Schubert scb->bufcnt = 0; 211*5796c8dcSSimon Schubert scb->bufp = scb->buf; 212*5796c8dcSSimon Schubert scb->error_fd = -1; 213*5796c8dcSSimon Schubert 214*5796c8dcSSimon Schubert /* `...->open (...)' would get expanded by an the open(2) syscall macro. */ 215*5796c8dcSSimon Schubert if ((*scb->ops->open) (scb, open_name)) 216*5796c8dcSSimon Schubert { 217*5796c8dcSSimon Schubert xfree (scb); 218*5796c8dcSSimon Schubert return NULL; 219*5796c8dcSSimon Schubert } 220*5796c8dcSSimon Schubert 221*5796c8dcSSimon Schubert scb->name = xstrdup (name); 222*5796c8dcSSimon Schubert scb->next = scb_base; 223*5796c8dcSSimon Schubert scb->refcnt = 1; 224*5796c8dcSSimon Schubert scb->debug_p = 0; 225*5796c8dcSSimon Schubert scb->async_state = 0; 226*5796c8dcSSimon Schubert scb->async_handler = NULL; 227*5796c8dcSSimon Schubert scb->async_context = NULL; 228*5796c8dcSSimon Schubert scb_base = scb; 229*5796c8dcSSimon Schubert 230*5796c8dcSSimon Schubert last_serial_opened = scb; 231*5796c8dcSSimon Schubert 232*5796c8dcSSimon Schubert if (serial_logfile != NULL) 233*5796c8dcSSimon Schubert { 234*5796c8dcSSimon Schubert serial_logfp = gdb_fopen (serial_logfile, "w"); 235*5796c8dcSSimon Schubert if (serial_logfp == NULL) 236*5796c8dcSSimon Schubert perror_with_name (serial_logfile); 237*5796c8dcSSimon Schubert } 238*5796c8dcSSimon Schubert 239*5796c8dcSSimon Schubert return scb; 240*5796c8dcSSimon Schubert } 241*5796c8dcSSimon Schubert 242*5796c8dcSSimon Schubert /* Return the open serial device for FD, if found, or NULL if FD 243*5796c8dcSSimon Schubert is not already opened. */ 244*5796c8dcSSimon Schubert 245*5796c8dcSSimon Schubert struct serial * 246*5796c8dcSSimon Schubert serial_for_fd (int fd) 247*5796c8dcSSimon Schubert { 248*5796c8dcSSimon Schubert struct serial *scb; 249*5796c8dcSSimon Schubert struct serial_ops *ops; 250*5796c8dcSSimon Schubert 251*5796c8dcSSimon Schubert for (scb = scb_base; scb; scb = scb->next) 252*5796c8dcSSimon Schubert if (scb->fd == fd) 253*5796c8dcSSimon Schubert return scb; 254*5796c8dcSSimon Schubert 255*5796c8dcSSimon Schubert return NULL; 256*5796c8dcSSimon Schubert } 257*5796c8dcSSimon Schubert 258*5796c8dcSSimon Schubert struct serial * 259*5796c8dcSSimon Schubert serial_fdopen (const int fd) 260*5796c8dcSSimon Schubert { 261*5796c8dcSSimon Schubert struct serial *scb; 262*5796c8dcSSimon Schubert struct serial_ops *ops; 263*5796c8dcSSimon Schubert 264*5796c8dcSSimon Schubert for (scb = scb_base; scb; scb = scb->next) 265*5796c8dcSSimon Schubert if (scb->fd == fd) 266*5796c8dcSSimon Schubert { 267*5796c8dcSSimon Schubert scb->refcnt++; 268*5796c8dcSSimon Schubert return scb; 269*5796c8dcSSimon Schubert } 270*5796c8dcSSimon Schubert 271*5796c8dcSSimon Schubert ops = serial_interface_lookup ("terminal"); 272*5796c8dcSSimon Schubert if (!ops) 273*5796c8dcSSimon Schubert ops = serial_interface_lookup ("hardwire"); 274*5796c8dcSSimon Schubert 275*5796c8dcSSimon Schubert if (!ops) 276*5796c8dcSSimon Schubert return NULL; 277*5796c8dcSSimon Schubert 278*5796c8dcSSimon Schubert scb = XCALLOC (1, struct serial); 279*5796c8dcSSimon Schubert 280*5796c8dcSSimon Schubert scb->ops = ops; 281*5796c8dcSSimon Schubert 282*5796c8dcSSimon Schubert scb->bufcnt = 0; 283*5796c8dcSSimon Schubert scb->bufp = scb->buf; 284*5796c8dcSSimon Schubert 285*5796c8dcSSimon Schubert scb->fd = fd; 286*5796c8dcSSimon Schubert 287*5796c8dcSSimon Schubert scb->name = NULL; 288*5796c8dcSSimon Schubert scb->next = scb_base; 289*5796c8dcSSimon Schubert scb->refcnt = 1; 290*5796c8dcSSimon Schubert scb->debug_p = 0; 291*5796c8dcSSimon Schubert scb->async_state = 0; 292*5796c8dcSSimon Schubert scb->async_handler = NULL; 293*5796c8dcSSimon Schubert scb->async_context = NULL; 294*5796c8dcSSimon Schubert scb_base = scb; 295*5796c8dcSSimon Schubert 296*5796c8dcSSimon Schubert last_serial_opened = scb; 297*5796c8dcSSimon Schubert 298*5796c8dcSSimon Schubert return scb; 299*5796c8dcSSimon Schubert } 300*5796c8dcSSimon Schubert 301*5796c8dcSSimon Schubert static void 302*5796c8dcSSimon Schubert do_serial_close (struct serial *scb, int really_close) 303*5796c8dcSSimon Schubert { 304*5796c8dcSSimon Schubert struct serial *tmp_scb; 305*5796c8dcSSimon Schubert 306*5796c8dcSSimon Schubert last_serial_opened = NULL; 307*5796c8dcSSimon Schubert 308*5796c8dcSSimon Schubert if (serial_logfp) 309*5796c8dcSSimon Schubert { 310*5796c8dcSSimon Schubert fputs_unfiltered ("\nEnd of log\n", serial_logfp); 311*5796c8dcSSimon Schubert serial_current_type = 0; 312*5796c8dcSSimon Schubert 313*5796c8dcSSimon Schubert /* XXX - What if serial_logfp == gdb_stdout or gdb_stderr? */ 314*5796c8dcSSimon Schubert ui_file_delete (serial_logfp); 315*5796c8dcSSimon Schubert serial_logfp = NULL; 316*5796c8dcSSimon Schubert } 317*5796c8dcSSimon Schubert 318*5796c8dcSSimon Schubert /* This is bogus. It's not our fault if you pass us a bad scb...! Rob, you 319*5796c8dcSSimon Schubert should fix your code instead. */ 320*5796c8dcSSimon Schubert 321*5796c8dcSSimon Schubert if (!scb) 322*5796c8dcSSimon Schubert return; 323*5796c8dcSSimon Schubert 324*5796c8dcSSimon Schubert scb->refcnt--; 325*5796c8dcSSimon Schubert if (scb->refcnt > 0) 326*5796c8dcSSimon Schubert return; 327*5796c8dcSSimon Schubert 328*5796c8dcSSimon Schubert /* ensure that the FD has been taken out of async mode */ 329*5796c8dcSSimon Schubert if (scb->async_handler != NULL) 330*5796c8dcSSimon Schubert serial_async (scb, NULL, NULL); 331*5796c8dcSSimon Schubert 332*5796c8dcSSimon Schubert if (really_close) 333*5796c8dcSSimon Schubert scb->ops->close (scb); 334*5796c8dcSSimon Schubert 335*5796c8dcSSimon Schubert if (scb->name) 336*5796c8dcSSimon Schubert xfree (scb->name); 337*5796c8dcSSimon Schubert 338*5796c8dcSSimon Schubert if (scb_base == scb) 339*5796c8dcSSimon Schubert scb_base = scb_base->next; 340*5796c8dcSSimon Schubert else 341*5796c8dcSSimon Schubert for (tmp_scb = scb_base; tmp_scb; tmp_scb = tmp_scb->next) 342*5796c8dcSSimon Schubert { 343*5796c8dcSSimon Schubert if (tmp_scb->next != scb) 344*5796c8dcSSimon Schubert continue; 345*5796c8dcSSimon Schubert 346*5796c8dcSSimon Schubert tmp_scb->next = tmp_scb->next->next; 347*5796c8dcSSimon Schubert break; 348*5796c8dcSSimon Schubert } 349*5796c8dcSSimon Schubert 350*5796c8dcSSimon Schubert xfree (scb); 351*5796c8dcSSimon Schubert } 352*5796c8dcSSimon Schubert 353*5796c8dcSSimon Schubert void 354*5796c8dcSSimon Schubert serial_close (struct serial *scb) 355*5796c8dcSSimon Schubert { 356*5796c8dcSSimon Schubert do_serial_close (scb, 1); 357*5796c8dcSSimon Schubert } 358*5796c8dcSSimon Schubert 359*5796c8dcSSimon Schubert void 360*5796c8dcSSimon Schubert serial_un_fdopen (struct serial *scb) 361*5796c8dcSSimon Schubert { 362*5796c8dcSSimon Schubert do_serial_close (scb, 0); 363*5796c8dcSSimon Schubert } 364*5796c8dcSSimon Schubert 365*5796c8dcSSimon Schubert int 366*5796c8dcSSimon Schubert serial_readchar (struct serial *scb, int timeout) 367*5796c8dcSSimon Schubert { 368*5796c8dcSSimon Schubert int ch; 369*5796c8dcSSimon Schubert 370*5796c8dcSSimon Schubert /* FIXME: cagney/1999-10-11: Don't enable this check until the ASYNC 371*5796c8dcSSimon Schubert code is finished. */ 372*5796c8dcSSimon Schubert if (0 && serial_is_async_p (scb) && timeout < 0) 373*5796c8dcSSimon Schubert internal_error (__FILE__, __LINE__, 374*5796c8dcSSimon Schubert _("serial_readchar: blocking read in async mode")); 375*5796c8dcSSimon Schubert 376*5796c8dcSSimon Schubert ch = scb->ops->readchar (scb, timeout); 377*5796c8dcSSimon Schubert if (serial_logfp != NULL) 378*5796c8dcSSimon Schubert { 379*5796c8dcSSimon Schubert serial_logchar (serial_logfp, 'r', ch, timeout); 380*5796c8dcSSimon Schubert 381*5796c8dcSSimon Schubert /* Make sure that the log file is as up-to-date as possible, 382*5796c8dcSSimon Schubert in case we are getting ready to dump core or something. */ 383*5796c8dcSSimon Schubert gdb_flush (serial_logfp); 384*5796c8dcSSimon Schubert } 385*5796c8dcSSimon Schubert if (serial_debug_p (scb)) 386*5796c8dcSSimon Schubert { 387*5796c8dcSSimon Schubert fprintf_unfiltered (gdb_stdlog, "["); 388*5796c8dcSSimon Schubert serial_logchar (gdb_stdlog, 'r', ch, timeout); 389*5796c8dcSSimon Schubert fprintf_unfiltered (gdb_stdlog, "]"); 390*5796c8dcSSimon Schubert gdb_flush (gdb_stdlog); 391*5796c8dcSSimon Schubert } 392*5796c8dcSSimon Schubert 393*5796c8dcSSimon Schubert return (ch); 394*5796c8dcSSimon Schubert } 395*5796c8dcSSimon Schubert 396*5796c8dcSSimon Schubert int 397*5796c8dcSSimon Schubert serial_write (struct serial *scb, const char *str, int len) 398*5796c8dcSSimon Schubert { 399*5796c8dcSSimon Schubert if (serial_logfp != NULL) 400*5796c8dcSSimon Schubert { 401*5796c8dcSSimon Schubert int count; 402*5796c8dcSSimon Schubert 403*5796c8dcSSimon Schubert for (count = 0; count < len; count++) 404*5796c8dcSSimon Schubert serial_logchar (serial_logfp, 'w', str[count] & 0xff, 0); 405*5796c8dcSSimon Schubert 406*5796c8dcSSimon Schubert /* Make sure that the log file is as up-to-date as possible, 407*5796c8dcSSimon Schubert in case we are getting ready to dump core or something. */ 408*5796c8dcSSimon Schubert gdb_flush (serial_logfp); 409*5796c8dcSSimon Schubert } 410*5796c8dcSSimon Schubert 411*5796c8dcSSimon Schubert return (scb->ops->write (scb, str, len)); 412*5796c8dcSSimon Schubert } 413*5796c8dcSSimon Schubert 414*5796c8dcSSimon Schubert void 415*5796c8dcSSimon Schubert serial_printf (struct serial *desc, const char *format,...) 416*5796c8dcSSimon Schubert { 417*5796c8dcSSimon Schubert va_list args; 418*5796c8dcSSimon Schubert char *buf; 419*5796c8dcSSimon Schubert va_start (args, format); 420*5796c8dcSSimon Schubert 421*5796c8dcSSimon Schubert buf = xstrvprintf (format, args); 422*5796c8dcSSimon Schubert serial_write (desc, buf, strlen (buf)); 423*5796c8dcSSimon Schubert 424*5796c8dcSSimon Schubert xfree (buf); 425*5796c8dcSSimon Schubert va_end (args); 426*5796c8dcSSimon Schubert } 427*5796c8dcSSimon Schubert 428*5796c8dcSSimon Schubert int 429*5796c8dcSSimon Schubert serial_drain_output (struct serial *scb) 430*5796c8dcSSimon Schubert { 431*5796c8dcSSimon Schubert return scb->ops->drain_output (scb); 432*5796c8dcSSimon Schubert } 433*5796c8dcSSimon Schubert 434*5796c8dcSSimon Schubert int 435*5796c8dcSSimon Schubert serial_flush_output (struct serial *scb) 436*5796c8dcSSimon Schubert { 437*5796c8dcSSimon Schubert return scb->ops->flush_output (scb); 438*5796c8dcSSimon Schubert } 439*5796c8dcSSimon Schubert 440*5796c8dcSSimon Schubert int 441*5796c8dcSSimon Schubert serial_flush_input (struct serial *scb) 442*5796c8dcSSimon Schubert { 443*5796c8dcSSimon Schubert return scb->ops->flush_input (scb); 444*5796c8dcSSimon Schubert } 445*5796c8dcSSimon Schubert 446*5796c8dcSSimon Schubert int 447*5796c8dcSSimon Schubert serial_send_break (struct serial *scb) 448*5796c8dcSSimon Schubert { 449*5796c8dcSSimon Schubert if (serial_logfp != NULL) 450*5796c8dcSSimon Schubert serial_logchar (serial_logfp, 'w', SERIAL_BREAK, 0); 451*5796c8dcSSimon Schubert 452*5796c8dcSSimon Schubert return (scb->ops->send_break (scb)); 453*5796c8dcSSimon Schubert } 454*5796c8dcSSimon Schubert 455*5796c8dcSSimon Schubert void 456*5796c8dcSSimon Schubert serial_raw (struct serial *scb) 457*5796c8dcSSimon Schubert { 458*5796c8dcSSimon Schubert scb->ops->go_raw (scb); 459*5796c8dcSSimon Schubert } 460*5796c8dcSSimon Schubert 461*5796c8dcSSimon Schubert serial_ttystate 462*5796c8dcSSimon Schubert serial_get_tty_state (struct serial *scb) 463*5796c8dcSSimon Schubert { 464*5796c8dcSSimon Schubert return scb->ops->get_tty_state (scb); 465*5796c8dcSSimon Schubert } 466*5796c8dcSSimon Schubert 467*5796c8dcSSimon Schubert int 468*5796c8dcSSimon Schubert serial_set_tty_state (struct serial *scb, serial_ttystate ttystate) 469*5796c8dcSSimon Schubert { 470*5796c8dcSSimon Schubert return scb->ops->set_tty_state (scb, ttystate); 471*5796c8dcSSimon Schubert } 472*5796c8dcSSimon Schubert 473*5796c8dcSSimon Schubert void 474*5796c8dcSSimon Schubert serial_print_tty_state (struct serial *scb, 475*5796c8dcSSimon Schubert serial_ttystate ttystate, 476*5796c8dcSSimon Schubert struct ui_file *stream) 477*5796c8dcSSimon Schubert { 478*5796c8dcSSimon Schubert scb->ops->print_tty_state (scb, ttystate, stream); 479*5796c8dcSSimon Schubert } 480*5796c8dcSSimon Schubert 481*5796c8dcSSimon Schubert int 482*5796c8dcSSimon Schubert serial_noflush_set_tty_state (struct serial *scb, 483*5796c8dcSSimon Schubert serial_ttystate new_ttystate, 484*5796c8dcSSimon Schubert serial_ttystate old_ttystate) 485*5796c8dcSSimon Schubert { 486*5796c8dcSSimon Schubert return scb->ops->noflush_set_tty_state (scb, new_ttystate, old_ttystate); 487*5796c8dcSSimon Schubert } 488*5796c8dcSSimon Schubert 489*5796c8dcSSimon Schubert int 490*5796c8dcSSimon Schubert serial_setbaudrate (struct serial *scb, int rate) 491*5796c8dcSSimon Schubert { 492*5796c8dcSSimon Schubert return scb->ops->setbaudrate (scb, rate); 493*5796c8dcSSimon Schubert } 494*5796c8dcSSimon Schubert 495*5796c8dcSSimon Schubert int 496*5796c8dcSSimon Schubert serial_setstopbits (struct serial *scb, int num) 497*5796c8dcSSimon Schubert { 498*5796c8dcSSimon Schubert return scb->ops->setstopbits (scb, num); 499*5796c8dcSSimon Schubert } 500*5796c8dcSSimon Schubert 501*5796c8dcSSimon Schubert int 502*5796c8dcSSimon Schubert serial_can_async_p (struct serial *scb) 503*5796c8dcSSimon Schubert { 504*5796c8dcSSimon Schubert return (scb->ops->async != NULL); 505*5796c8dcSSimon Schubert } 506*5796c8dcSSimon Schubert 507*5796c8dcSSimon Schubert int 508*5796c8dcSSimon Schubert serial_is_async_p (struct serial *scb) 509*5796c8dcSSimon Schubert { 510*5796c8dcSSimon Schubert return (scb->ops->async != NULL) && (scb->async_handler != NULL); 511*5796c8dcSSimon Schubert } 512*5796c8dcSSimon Schubert 513*5796c8dcSSimon Schubert void 514*5796c8dcSSimon Schubert serial_async (struct serial *scb, 515*5796c8dcSSimon Schubert serial_event_ftype *handler, 516*5796c8dcSSimon Schubert void *context) 517*5796c8dcSSimon Schubert { 518*5796c8dcSSimon Schubert int changed = ((scb->async_handler == NULL) != (handler == NULL)); 519*5796c8dcSSimon Schubert scb->async_handler = handler; 520*5796c8dcSSimon Schubert scb->async_context = context; 521*5796c8dcSSimon Schubert /* Only change mode if there is a need. */ 522*5796c8dcSSimon Schubert if (changed) 523*5796c8dcSSimon Schubert scb->ops->async (scb, handler != NULL); 524*5796c8dcSSimon Schubert } 525*5796c8dcSSimon Schubert 526*5796c8dcSSimon Schubert int 527*5796c8dcSSimon Schubert deprecated_serial_fd (struct serial *scb) 528*5796c8dcSSimon Schubert { 529*5796c8dcSSimon Schubert /* FIXME: should this output a warning that deprecated code is being 530*5796c8dcSSimon Schubert called? */ 531*5796c8dcSSimon Schubert if (scb->fd < 0) 532*5796c8dcSSimon Schubert { 533*5796c8dcSSimon Schubert internal_error (__FILE__, __LINE__, 534*5796c8dcSSimon Schubert _("serial: FD not valid")); 535*5796c8dcSSimon Schubert } 536*5796c8dcSSimon Schubert return scb->fd; /* sigh */ 537*5796c8dcSSimon Schubert } 538*5796c8dcSSimon Schubert 539*5796c8dcSSimon Schubert void 540*5796c8dcSSimon Schubert serial_debug (struct serial *scb, int debug_p) 541*5796c8dcSSimon Schubert { 542*5796c8dcSSimon Schubert scb->debug_p = debug_p; 543*5796c8dcSSimon Schubert } 544*5796c8dcSSimon Schubert 545*5796c8dcSSimon Schubert int 546*5796c8dcSSimon Schubert serial_debug_p (struct serial *scb) 547*5796c8dcSSimon Schubert { 548*5796c8dcSSimon Schubert return scb->debug_p || global_serial_debug_p; 549*5796c8dcSSimon Schubert } 550*5796c8dcSSimon Schubert 551*5796c8dcSSimon Schubert #ifdef USE_WIN32API 552*5796c8dcSSimon Schubert void 553*5796c8dcSSimon Schubert serial_wait_handle (struct serial *scb, HANDLE *read, HANDLE *except) 554*5796c8dcSSimon Schubert { 555*5796c8dcSSimon Schubert if (scb->ops->wait_handle) 556*5796c8dcSSimon Schubert scb->ops->wait_handle (scb, read, except); 557*5796c8dcSSimon Schubert else 558*5796c8dcSSimon Schubert { 559*5796c8dcSSimon Schubert *read = (HANDLE) _get_osfhandle (scb->fd); 560*5796c8dcSSimon Schubert *except = NULL; 561*5796c8dcSSimon Schubert } 562*5796c8dcSSimon Schubert } 563*5796c8dcSSimon Schubert 564*5796c8dcSSimon Schubert void 565*5796c8dcSSimon Schubert serial_done_wait_handle (struct serial *scb) 566*5796c8dcSSimon Schubert { 567*5796c8dcSSimon Schubert if (scb->ops->done_wait_handle) 568*5796c8dcSSimon Schubert scb->ops->done_wait_handle (scb); 569*5796c8dcSSimon Schubert } 570*5796c8dcSSimon Schubert #endif 571*5796c8dcSSimon Schubert 572*5796c8dcSSimon Schubert #if 0 573*5796c8dcSSimon Schubert /* The connect command is #if 0 because I hadn't thought of an elegant 574*5796c8dcSSimon Schubert way to wait for I/O on two `struct serial *'s simultaneously. Two 575*5796c8dcSSimon Schubert solutions came to mind: 576*5796c8dcSSimon Schubert 577*5796c8dcSSimon Schubert 1) Fork, and have have one fork handle the to user direction, 578*5796c8dcSSimon Schubert and have the other hand the to target direction. This 579*5796c8dcSSimon Schubert obviously won't cut it for MSDOS. 580*5796c8dcSSimon Schubert 581*5796c8dcSSimon Schubert 2) Use something like select. This assumes that stdin and 582*5796c8dcSSimon Schubert the target side can both be waited on via the same 583*5796c8dcSSimon Schubert mechanism. This may not be true for DOS, if GDB is 584*5796c8dcSSimon Schubert talking to the target via a TCP socket. 585*5796c8dcSSimon Schubert -grossman, 8 Jun 93 */ 586*5796c8dcSSimon Schubert 587*5796c8dcSSimon Schubert /* Connect the user directly to the remote system. This command acts just like 588*5796c8dcSSimon Schubert the 'cu' or 'tip' command. Use <CR>~. or <CR>~^D to break out. */ 589*5796c8dcSSimon Schubert 590*5796c8dcSSimon Schubert static struct serial *tty_desc; /* Controlling terminal */ 591*5796c8dcSSimon Schubert 592*5796c8dcSSimon Schubert static void 593*5796c8dcSSimon Schubert cleanup_tty (serial_ttystate ttystate) 594*5796c8dcSSimon Schubert { 595*5796c8dcSSimon Schubert printf_unfiltered ("\r\n[Exiting connect mode]\r\n"); 596*5796c8dcSSimon Schubert serial_set_tty_state (tty_desc, ttystate); 597*5796c8dcSSimon Schubert xfree (ttystate); 598*5796c8dcSSimon Schubert serial_close (tty_desc); 599*5796c8dcSSimon Schubert } 600*5796c8dcSSimon Schubert 601*5796c8dcSSimon Schubert static void 602*5796c8dcSSimon Schubert connect_command (char *args, int fromtty) 603*5796c8dcSSimon Schubert { 604*5796c8dcSSimon Schubert int c; 605*5796c8dcSSimon Schubert char cur_esc = 0; 606*5796c8dcSSimon Schubert serial_ttystate ttystate; 607*5796c8dcSSimon Schubert struct serial *port_desc; /* TTY port */ 608*5796c8dcSSimon Schubert 609*5796c8dcSSimon Schubert dont_repeat (); 610*5796c8dcSSimon Schubert 611*5796c8dcSSimon Schubert if (args) 612*5796c8dcSSimon Schubert fprintf_unfiltered (gdb_stderr, "This command takes no args. They have been ignored.\n"); 613*5796c8dcSSimon Schubert 614*5796c8dcSSimon Schubert printf_unfiltered ("[Entering connect mode. Use ~. or ~^D to escape]\n"); 615*5796c8dcSSimon Schubert 616*5796c8dcSSimon Schubert tty_desc = serial_fdopen (0); 617*5796c8dcSSimon Schubert port_desc = last_serial_opened; 618*5796c8dcSSimon Schubert 619*5796c8dcSSimon Schubert ttystate = serial_get_tty_state (tty_desc); 620*5796c8dcSSimon Schubert 621*5796c8dcSSimon Schubert serial_raw (tty_desc); 622*5796c8dcSSimon Schubert serial_raw (port_desc); 623*5796c8dcSSimon Schubert 624*5796c8dcSSimon Schubert make_cleanup (cleanup_tty, ttystate); 625*5796c8dcSSimon Schubert 626*5796c8dcSSimon Schubert while (1) 627*5796c8dcSSimon Schubert { 628*5796c8dcSSimon Schubert int mask; 629*5796c8dcSSimon Schubert 630*5796c8dcSSimon Schubert mask = serial_wait_2 (tty_desc, port_desc, -1); 631*5796c8dcSSimon Schubert 632*5796c8dcSSimon Schubert if (mask & 2) 633*5796c8dcSSimon Schubert { /* tty input */ 634*5796c8dcSSimon Schubert char cx; 635*5796c8dcSSimon Schubert 636*5796c8dcSSimon Schubert while (1) 637*5796c8dcSSimon Schubert { 638*5796c8dcSSimon Schubert c = serial_readchar (tty_desc, 0); 639*5796c8dcSSimon Schubert 640*5796c8dcSSimon Schubert if (c == SERIAL_TIMEOUT) 641*5796c8dcSSimon Schubert break; 642*5796c8dcSSimon Schubert 643*5796c8dcSSimon Schubert if (c < 0) 644*5796c8dcSSimon Schubert perror_with_name (_("connect")); 645*5796c8dcSSimon Schubert 646*5796c8dcSSimon Schubert cx = c; 647*5796c8dcSSimon Schubert serial_write (port_desc, &cx, 1); 648*5796c8dcSSimon Schubert 649*5796c8dcSSimon Schubert switch (cur_esc) 650*5796c8dcSSimon Schubert { 651*5796c8dcSSimon Schubert case 0: 652*5796c8dcSSimon Schubert if (c == '\r') 653*5796c8dcSSimon Schubert cur_esc = c; 654*5796c8dcSSimon Schubert break; 655*5796c8dcSSimon Schubert case '\r': 656*5796c8dcSSimon Schubert if (c == '~') 657*5796c8dcSSimon Schubert cur_esc = c; 658*5796c8dcSSimon Schubert else 659*5796c8dcSSimon Schubert cur_esc = 0; 660*5796c8dcSSimon Schubert break; 661*5796c8dcSSimon Schubert case '~': 662*5796c8dcSSimon Schubert if (c == '.' || c == '\004') 663*5796c8dcSSimon Schubert return; 664*5796c8dcSSimon Schubert else 665*5796c8dcSSimon Schubert cur_esc = 0; 666*5796c8dcSSimon Schubert } 667*5796c8dcSSimon Schubert } 668*5796c8dcSSimon Schubert } 669*5796c8dcSSimon Schubert 670*5796c8dcSSimon Schubert if (mask & 1) 671*5796c8dcSSimon Schubert { /* Port input */ 672*5796c8dcSSimon Schubert char cx; 673*5796c8dcSSimon Schubert 674*5796c8dcSSimon Schubert while (1) 675*5796c8dcSSimon Schubert { 676*5796c8dcSSimon Schubert c = serial_readchar (port_desc, 0); 677*5796c8dcSSimon Schubert 678*5796c8dcSSimon Schubert if (c == SERIAL_TIMEOUT) 679*5796c8dcSSimon Schubert break; 680*5796c8dcSSimon Schubert 681*5796c8dcSSimon Schubert if (c < 0) 682*5796c8dcSSimon Schubert perror_with_name (_("connect")); 683*5796c8dcSSimon Schubert 684*5796c8dcSSimon Schubert cx = c; 685*5796c8dcSSimon Schubert 686*5796c8dcSSimon Schubert serial_write (tty_desc, &cx, 1); 687*5796c8dcSSimon Schubert } 688*5796c8dcSSimon Schubert } 689*5796c8dcSSimon Schubert } 690*5796c8dcSSimon Schubert } 691*5796c8dcSSimon Schubert #endif /* 0 */ 692*5796c8dcSSimon Schubert 693*5796c8dcSSimon Schubert /* Serial set/show framework. */ 694*5796c8dcSSimon Schubert 695*5796c8dcSSimon Schubert static struct cmd_list_element *serial_set_cmdlist; 696*5796c8dcSSimon Schubert static struct cmd_list_element *serial_show_cmdlist; 697*5796c8dcSSimon Schubert 698*5796c8dcSSimon Schubert static void 699*5796c8dcSSimon Schubert serial_set_cmd (char *args, int from_tty) 700*5796c8dcSSimon Schubert { 701*5796c8dcSSimon Schubert printf_unfiltered ("\"set serial\" must be followed by the name of a command.\n"); 702*5796c8dcSSimon Schubert help_list (serial_set_cmdlist, "set serial ", -1, gdb_stdout); 703*5796c8dcSSimon Schubert } 704*5796c8dcSSimon Schubert 705*5796c8dcSSimon Schubert static void 706*5796c8dcSSimon Schubert serial_show_cmd (char *args, int from_tty) 707*5796c8dcSSimon Schubert { 708*5796c8dcSSimon Schubert cmd_show_list (serial_show_cmdlist, from_tty, ""); 709*5796c8dcSSimon Schubert } 710*5796c8dcSSimon Schubert 711*5796c8dcSSimon Schubert 712*5796c8dcSSimon Schubert void 713*5796c8dcSSimon Schubert _initialize_serial (void) 714*5796c8dcSSimon Schubert { 715*5796c8dcSSimon Schubert #if 0 716*5796c8dcSSimon Schubert add_com ("connect", class_obscure, connect_command, _("\ 717*5796c8dcSSimon Schubert Connect the terminal directly up to the command monitor.\n\ 718*5796c8dcSSimon Schubert Use <CR>~. or <CR>~^D to break out.")); 719*5796c8dcSSimon Schubert #endif /* 0 */ 720*5796c8dcSSimon Schubert 721*5796c8dcSSimon Schubert add_prefix_cmd ("serial", class_maintenance, serial_set_cmd, _("\ 722*5796c8dcSSimon Schubert Set default serial/parallel port configuration."), 723*5796c8dcSSimon Schubert &serial_set_cmdlist, "set serial ", 724*5796c8dcSSimon Schubert 0/*allow-unknown*/, 725*5796c8dcSSimon Schubert &setlist); 726*5796c8dcSSimon Schubert 727*5796c8dcSSimon Schubert add_prefix_cmd ("serial", class_maintenance, serial_show_cmd, _("\ 728*5796c8dcSSimon Schubert Show default serial/parallel port configuration."), 729*5796c8dcSSimon Schubert &serial_show_cmdlist, "show serial ", 730*5796c8dcSSimon Schubert 0/*allow-unknown*/, 731*5796c8dcSSimon Schubert &showlist); 732*5796c8dcSSimon Schubert 733*5796c8dcSSimon Schubert add_setshow_filename_cmd ("remotelogfile", no_class, &serial_logfile, _("\ 734*5796c8dcSSimon Schubert Set filename for remote session recording."), _("\ 735*5796c8dcSSimon Schubert Show filename for remote session recording."), _("\ 736*5796c8dcSSimon Schubert This file is used to record the remote session for future playback\n\ 737*5796c8dcSSimon Schubert by gdbserver."), 738*5796c8dcSSimon Schubert NULL, 739*5796c8dcSSimon Schubert NULL, /* FIXME: i18n: */ 740*5796c8dcSSimon Schubert &setlist, &showlist); 741*5796c8dcSSimon Schubert 742*5796c8dcSSimon Schubert add_setshow_enum_cmd ("remotelogbase", no_class, logbase_enums, 743*5796c8dcSSimon Schubert &serial_logbase, _("\ 744*5796c8dcSSimon Schubert Set numerical base for remote session logging"), _("\ 745*5796c8dcSSimon Schubert Show numerical base for remote session logging"), NULL, 746*5796c8dcSSimon Schubert NULL, 747*5796c8dcSSimon Schubert NULL, /* FIXME: i18n: */ 748*5796c8dcSSimon Schubert &setlist, &showlist); 749*5796c8dcSSimon Schubert 750*5796c8dcSSimon Schubert add_setshow_zinteger_cmd ("serial", class_maintenance, 751*5796c8dcSSimon Schubert &global_serial_debug_p, _("\ 752*5796c8dcSSimon Schubert Set serial debugging."), _("\ 753*5796c8dcSSimon Schubert Show serial debugging."), _("\ 754*5796c8dcSSimon Schubert When non-zero, serial port debugging is enabled."), 755*5796c8dcSSimon Schubert NULL, 756*5796c8dcSSimon Schubert NULL, /* FIXME: i18n: */ 757*5796c8dcSSimon Schubert &setdebuglist, &showdebuglist); 758*5796c8dcSSimon Schubert } 759