xref: /dflybsd-src/contrib/gdb-7/gdb/serial.c (revision c50c785cb49e9377ca78104c5540c7b33f768771)
15796c8dcSSimon Schubert /* Generic serial interface routines
25796c8dcSSimon Schubert 
35796c8dcSSimon Schubert    Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
4*c50c785cSJohn Marino    2002, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
5cf7f2e2dSJohn Marino    Free Software Foundation, Inc.
65796c8dcSSimon Schubert 
75796c8dcSSimon Schubert    This file is part of GDB.
85796c8dcSSimon Schubert 
95796c8dcSSimon Schubert    This program is free software; you can redistribute it and/or modify
105796c8dcSSimon Schubert    it under the terms of the GNU General Public License as published by
115796c8dcSSimon Schubert    the Free Software Foundation; either version 3 of the License, or
125796c8dcSSimon Schubert    (at your option) any later version.
135796c8dcSSimon Schubert 
145796c8dcSSimon Schubert    This program is distributed in the hope that it will be useful,
155796c8dcSSimon Schubert    but WITHOUT ANY WARRANTY; without even the implied warranty of
165796c8dcSSimon Schubert    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
175796c8dcSSimon Schubert    GNU General Public License for more details.
185796c8dcSSimon Schubert 
195796c8dcSSimon Schubert    You should have received a copy of the GNU General Public License
205796c8dcSSimon Schubert    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
215796c8dcSSimon Schubert 
225796c8dcSSimon Schubert #include "defs.h"
235796c8dcSSimon Schubert #include <ctype.h>
245796c8dcSSimon Schubert #include "serial.h"
255796c8dcSSimon Schubert #include "gdb_string.h"
265796c8dcSSimon Schubert #include "gdbcmd.h"
275796c8dcSSimon Schubert 
285796c8dcSSimon Schubert extern void _initialize_serial (void);
295796c8dcSSimon Schubert 
305796c8dcSSimon Schubert /* Is serial being debugged?  */
315796c8dcSSimon Schubert 
325796c8dcSSimon Schubert static int global_serial_debug_p;
335796c8dcSSimon Schubert 
34*c50c785cSJohn Marino /* Linked list of serial I/O handlers.  */
355796c8dcSSimon Schubert 
365796c8dcSSimon Schubert static struct serial_ops *serial_ops_list = NULL;
375796c8dcSSimon Schubert 
385796c8dcSSimon Schubert /* This is the last serial stream opened.  Used by connect command.  */
395796c8dcSSimon Schubert 
405796c8dcSSimon Schubert static struct serial *last_serial_opened = NULL;
415796c8dcSSimon Schubert 
425796c8dcSSimon Schubert /* Pointer to list of scb's.  */
435796c8dcSSimon Schubert 
445796c8dcSSimon Schubert static struct serial *scb_base;
455796c8dcSSimon Schubert 
465796c8dcSSimon Schubert /* Non-NULL gives filename which contains a recording of the remote session,
475796c8dcSSimon Schubert    suitable for playback by gdbserver.  */
485796c8dcSSimon Schubert 
495796c8dcSSimon Schubert static char *serial_logfile = NULL;
505796c8dcSSimon Schubert static struct ui_file *serial_logfp = NULL;
515796c8dcSSimon Schubert 
52*c50c785cSJohn Marino static struct serial_ops *serial_interface_lookup (const char *);
53*c50c785cSJohn Marino static void serial_logchar (struct ui_file *stream,
54*c50c785cSJohn Marino 			    int ch_type, int ch, int timeout);
555796c8dcSSimon Schubert static const char logbase_hex[] = "hex";
565796c8dcSSimon Schubert static const char logbase_octal[] = "octal";
575796c8dcSSimon Schubert static const char logbase_ascii[] = "ascii";
585796c8dcSSimon Schubert static const char *logbase_enums[] =
595796c8dcSSimon Schubert {logbase_hex, logbase_octal, logbase_ascii, NULL};
605796c8dcSSimon Schubert static const char *serial_logbase = logbase_ascii;
615796c8dcSSimon Schubert 
625796c8dcSSimon Schubert 
635796c8dcSSimon Schubert static int serial_current_type = 0;
645796c8dcSSimon Schubert 
65*c50c785cSJohn Marino /* Log char CH of type CHTYPE, with TIMEOUT.  */
665796c8dcSSimon Schubert 
675796c8dcSSimon Schubert /* Define bogus char to represent a BREAK.  Should be careful to choose a value
685796c8dcSSimon Schubert    that can't be confused with a normal char, or an error code.  */
695796c8dcSSimon Schubert #define SERIAL_BREAK 1235
705796c8dcSSimon Schubert 
715796c8dcSSimon Schubert static void
725796c8dcSSimon Schubert serial_logchar (struct ui_file *stream, int ch_type, int ch, int timeout)
735796c8dcSSimon Schubert {
745796c8dcSSimon Schubert   if (ch_type != serial_current_type)
755796c8dcSSimon Schubert     {
765796c8dcSSimon Schubert       fprintf_unfiltered (stream, "\n%c ", ch_type);
775796c8dcSSimon Schubert       serial_current_type = ch_type;
785796c8dcSSimon Schubert     }
795796c8dcSSimon Schubert 
805796c8dcSSimon Schubert   if (serial_logbase != logbase_ascii)
815796c8dcSSimon Schubert     fputc_unfiltered (' ', stream);
825796c8dcSSimon Schubert 
835796c8dcSSimon Schubert   switch (ch)
845796c8dcSSimon Schubert     {
855796c8dcSSimon Schubert     case SERIAL_TIMEOUT:
865796c8dcSSimon Schubert       fprintf_unfiltered (stream, "<Timeout: %d seconds>", timeout);
875796c8dcSSimon Schubert       return;
885796c8dcSSimon Schubert     case SERIAL_ERROR:
895796c8dcSSimon Schubert       fprintf_unfiltered (stream, "<Error: %s>", safe_strerror (errno));
905796c8dcSSimon Schubert       return;
915796c8dcSSimon Schubert     case SERIAL_EOF:
925796c8dcSSimon Schubert       fputs_unfiltered ("<Eof>", stream);
935796c8dcSSimon Schubert       return;
945796c8dcSSimon Schubert     case SERIAL_BREAK:
955796c8dcSSimon Schubert       fputs_unfiltered ("<Break>", stream);
965796c8dcSSimon Schubert       return;
975796c8dcSSimon Schubert     default:
985796c8dcSSimon Schubert       if (serial_logbase == logbase_hex)
995796c8dcSSimon Schubert 	fprintf_unfiltered (stream, "%02x", ch & 0xff);
1005796c8dcSSimon Schubert       else if (serial_logbase == logbase_octal)
1015796c8dcSSimon Schubert 	fprintf_unfiltered (stream, "%03o", ch & 0xff);
1025796c8dcSSimon Schubert       else
1035796c8dcSSimon Schubert 	switch (ch)
1045796c8dcSSimon Schubert 	  {
1055796c8dcSSimon Schubert 	  case '\\':
1065796c8dcSSimon Schubert 	    fputs_unfiltered ("\\\\", stream);
1075796c8dcSSimon Schubert 	    break;
1085796c8dcSSimon Schubert 	  case '\b':
1095796c8dcSSimon Schubert 	    fputs_unfiltered ("\\b", stream);
1105796c8dcSSimon Schubert 	    break;
1115796c8dcSSimon Schubert 	  case '\f':
1125796c8dcSSimon Schubert 	    fputs_unfiltered ("\\f", stream);
1135796c8dcSSimon Schubert 	    break;
1145796c8dcSSimon Schubert 	  case '\n':
1155796c8dcSSimon Schubert 	    fputs_unfiltered ("\\n", stream);
1165796c8dcSSimon Schubert 	    break;
1175796c8dcSSimon Schubert 	  case '\r':
1185796c8dcSSimon Schubert 	    fputs_unfiltered ("\\r", stream);
1195796c8dcSSimon Schubert 	    break;
1205796c8dcSSimon Schubert 	  case '\t':
1215796c8dcSSimon Schubert 	    fputs_unfiltered ("\\t", stream);
1225796c8dcSSimon Schubert 	    break;
1235796c8dcSSimon Schubert 	  case '\v':
1245796c8dcSSimon Schubert 	    fputs_unfiltered ("\\v", stream);
1255796c8dcSSimon Schubert 	    break;
1265796c8dcSSimon Schubert 	  default:
127*c50c785cSJohn Marino 	    fprintf_unfiltered (stream,
128*c50c785cSJohn Marino 				isprint (ch) ? "%c" : "\\x%02x", ch & 0xFF);
1295796c8dcSSimon Schubert 	    break;
1305796c8dcSSimon Schubert 	  }
1315796c8dcSSimon Schubert     }
1325796c8dcSSimon Schubert }
1335796c8dcSSimon Schubert 
1345796c8dcSSimon Schubert void
1355796c8dcSSimon Schubert serial_log_command (const char *cmd)
1365796c8dcSSimon Schubert {
1375796c8dcSSimon Schubert   if (!serial_logfp)
1385796c8dcSSimon Schubert     return;
1395796c8dcSSimon Schubert 
1405796c8dcSSimon Schubert   serial_current_type = 'c';
1415796c8dcSSimon Schubert 
1425796c8dcSSimon Schubert   fputs_unfiltered ("\nc ", serial_logfp);
1435796c8dcSSimon Schubert   fputs_unfiltered (cmd, serial_logfp);
1445796c8dcSSimon Schubert 
1455796c8dcSSimon Schubert   /* Make sure that the log file is as up-to-date as possible,
1465796c8dcSSimon Schubert      in case we are getting ready to dump core or something.  */
1475796c8dcSSimon Schubert   gdb_flush (serial_logfp);
1485796c8dcSSimon Schubert }
1495796c8dcSSimon Schubert 
1505796c8dcSSimon Schubert 
1515796c8dcSSimon Schubert static struct serial_ops *
152*c50c785cSJohn Marino serial_interface_lookup (const char *name)
1535796c8dcSSimon Schubert {
1545796c8dcSSimon Schubert   struct serial_ops *ops;
1555796c8dcSSimon Schubert 
1565796c8dcSSimon Schubert   for (ops = serial_ops_list; ops; ops = ops->next)
1575796c8dcSSimon Schubert     if (strcmp (name, ops->name) == 0)
1585796c8dcSSimon Schubert       return ops;
1595796c8dcSSimon Schubert 
1605796c8dcSSimon Schubert   return NULL;
1615796c8dcSSimon Schubert }
1625796c8dcSSimon Schubert 
1635796c8dcSSimon Schubert void
1645796c8dcSSimon Schubert serial_add_interface (struct serial_ops *optable)
1655796c8dcSSimon Schubert {
1665796c8dcSSimon Schubert   optable->next = serial_ops_list;
1675796c8dcSSimon Schubert   serial_ops_list = optable;
1685796c8dcSSimon Schubert }
1695796c8dcSSimon Schubert 
1705796c8dcSSimon Schubert /* Open up a device or a network socket, depending upon the syntax of NAME.  */
1715796c8dcSSimon Schubert 
1725796c8dcSSimon Schubert struct serial *
1735796c8dcSSimon Schubert serial_open (const char *name)
1745796c8dcSSimon Schubert {
1755796c8dcSSimon Schubert   struct serial *scb;
1765796c8dcSSimon Schubert   struct serial_ops *ops;
1775796c8dcSSimon Schubert   const char *open_name = name;
1785796c8dcSSimon Schubert 
1795796c8dcSSimon Schubert   for (scb = scb_base; scb; scb = scb->next)
1805796c8dcSSimon Schubert     if (scb->name && strcmp (scb->name, name) == 0)
1815796c8dcSSimon Schubert       {
1825796c8dcSSimon Schubert 	scb->refcnt++;
1835796c8dcSSimon Schubert 	return scb;
1845796c8dcSSimon Schubert       }
1855796c8dcSSimon Schubert 
1865796c8dcSSimon Schubert   if (strcmp (name, "pc") == 0)
1875796c8dcSSimon Schubert     ops = serial_interface_lookup ("pc");
1885796c8dcSSimon Schubert   else if (strncmp (name, "lpt", 3) == 0)
1895796c8dcSSimon Schubert     ops = serial_interface_lookup ("parallel");
1905796c8dcSSimon Schubert   else if (strncmp (name, "|", 1) == 0)
1915796c8dcSSimon Schubert     {
1925796c8dcSSimon Schubert       ops = serial_interface_lookup ("pipe");
1935796c8dcSSimon Schubert       /* Discard ``|'' and any space before the command itself.  */
1945796c8dcSSimon Schubert       ++open_name;
1955796c8dcSSimon Schubert       while (isspace (*open_name))
1965796c8dcSSimon Schubert 	++open_name;
1975796c8dcSSimon Schubert     }
1985796c8dcSSimon Schubert   /* Check for a colon, suggesting an IP address/port pair.
1995796c8dcSSimon Schubert      Do this *after* checking for all the interesting prefixes.  We
2005796c8dcSSimon Schubert      don't want to constrain the syntax of what can follow them.  */
2015796c8dcSSimon Schubert   else if (strchr (name, ':'))
2025796c8dcSSimon Schubert     ops = serial_interface_lookup ("tcp");
2035796c8dcSSimon Schubert   else
2045796c8dcSSimon Schubert     ops = serial_interface_lookup ("hardwire");
2055796c8dcSSimon Schubert 
2065796c8dcSSimon Schubert   if (!ops)
2075796c8dcSSimon Schubert     return NULL;
2085796c8dcSSimon Schubert 
2095796c8dcSSimon Schubert   scb = XMALLOC (struct serial);
2105796c8dcSSimon Schubert 
2115796c8dcSSimon Schubert   scb->ops = ops;
2125796c8dcSSimon Schubert 
2135796c8dcSSimon Schubert   scb->bufcnt = 0;
2145796c8dcSSimon Schubert   scb->bufp = scb->buf;
2155796c8dcSSimon Schubert   scb->error_fd = -1;
2165796c8dcSSimon Schubert 
217*c50c785cSJohn Marino   /* `...->open (...)' would get expanded by the open(2) syscall macro.  */
2185796c8dcSSimon Schubert   if ((*scb->ops->open) (scb, open_name))
2195796c8dcSSimon Schubert     {
2205796c8dcSSimon Schubert       xfree (scb);
2215796c8dcSSimon Schubert       return NULL;
2225796c8dcSSimon Schubert     }
2235796c8dcSSimon Schubert 
2245796c8dcSSimon Schubert   scb->name = xstrdup (name);
2255796c8dcSSimon Schubert   scb->next = scb_base;
2265796c8dcSSimon Schubert   scb->refcnt = 1;
2275796c8dcSSimon Schubert   scb->debug_p = 0;
2285796c8dcSSimon Schubert   scb->async_state = 0;
2295796c8dcSSimon Schubert   scb->async_handler = NULL;
2305796c8dcSSimon Schubert   scb->async_context = NULL;
2315796c8dcSSimon Schubert   scb_base = scb;
2325796c8dcSSimon Schubert 
2335796c8dcSSimon Schubert   last_serial_opened = scb;
2345796c8dcSSimon Schubert 
2355796c8dcSSimon Schubert   if (serial_logfile != NULL)
2365796c8dcSSimon Schubert     {
2375796c8dcSSimon Schubert       serial_logfp = gdb_fopen (serial_logfile, "w");
2385796c8dcSSimon Schubert       if (serial_logfp == NULL)
2395796c8dcSSimon Schubert 	perror_with_name (serial_logfile);
2405796c8dcSSimon Schubert     }
2415796c8dcSSimon Schubert 
2425796c8dcSSimon Schubert   return scb;
2435796c8dcSSimon Schubert }
2445796c8dcSSimon Schubert 
2455796c8dcSSimon Schubert /* Return the open serial device for FD, if found, or NULL if FD
2465796c8dcSSimon Schubert    is not already opened.  */
2475796c8dcSSimon Schubert 
2485796c8dcSSimon Schubert struct serial *
2495796c8dcSSimon Schubert serial_for_fd (int fd)
2505796c8dcSSimon Schubert {
2515796c8dcSSimon Schubert   struct serial *scb;
2525796c8dcSSimon Schubert 
2535796c8dcSSimon Schubert   for (scb = scb_base; scb; scb = scb->next)
2545796c8dcSSimon Schubert     if (scb->fd == fd)
2555796c8dcSSimon Schubert       return scb;
2565796c8dcSSimon Schubert 
2575796c8dcSSimon Schubert   return NULL;
2585796c8dcSSimon Schubert }
2595796c8dcSSimon Schubert 
260*c50c785cSJohn Marino /* Open a new serial stream using a file handle, using serial
261*c50c785cSJohn Marino    interface ops OPS.  */
262*c50c785cSJohn Marino 
263*c50c785cSJohn Marino static struct serial *
264*c50c785cSJohn Marino serial_fdopen_ops (const int fd, struct serial_ops *ops)
2655796c8dcSSimon Schubert {
2665796c8dcSSimon Schubert   struct serial *scb;
2675796c8dcSSimon Schubert 
268*c50c785cSJohn Marino   scb = serial_for_fd (fd);
269*c50c785cSJohn Marino   if (scb)
2705796c8dcSSimon Schubert     {
2715796c8dcSSimon Schubert       scb->refcnt++;
2725796c8dcSSimon Schubert       return scb;
2735796c8dcSSimon Schubert     }
2745796c8dcSSimon Schubert 
275*c50c785cSJohn Marino   if (!ops)
276*c50c785cSJohn Marino     {
2775796c8dcSSimon Schubert       ops = serial_interface_lookup ("terminal");
2785796c8dcSSimon Schubert       if (!ops)
2795796c8dcSSimon Schubert  	ops = serial_interface_lookup ("hardwire");
280*c50c785cSJohn Marino     }
2815796c8dcSSimon Schubert 
2825796c8dcSSimon Schubert   if (!ops)
2835796c8dcSSimon Schubert     return NULL;
2845796c8dcSSimon Schubert 
2855796c8dcSSimon Schubert   scb = XCALLOC (1, struct serial);
2865796c8dcSSimon Schubert 
2875796c8dcSSimon Schubert   scb->ops = ops;
2885796c8dcSSimon Schubert 
2895796c8dcSSimon Schubert   scb->bufcnt = 0;
2905796c8dcSSimon Schubert   scb->bufp = scb->buf;
291*c50c785cSJohn Marino   scb->error_fd = -1;
2925796c8dcSSimon Schubert 
2935796c8dcSSimon Schubert   scb->name = NULL;
2945796c8dcSSimon Schubert   scb->next = scb_base;
2955796c8dcSSimon Schubert   scb->refcnt = 1;
2965796c8dcSSimon Schubert   scb->debug_p = 0;
2975796c8dcSSimon Schubert   scb->async_state = 0;
2985796c8dcSSimon Schubert   scb->async_handler = NULL;
2995796c8dcSSimon Schubert   scb->async_context = NULL;
3005796c8dcSSimon Schubert   scb_base = scb;
3015796c8dcSSimon Schubert 
302*c50c785cSJohn Marino   if ((ops->fdopen) != NULL)
303*c50c785cSJohn Marino     (*ops->fdopen) (scb, fd);
304*c50c785cSJohn Marino   else
305*c50c785cSJohn Marino     scb->fd = fd;
306*c50c785cSJohn Marino 
3075796c8dcSSimon Schubert   last_serial_opened = scb;
3085796c8dcSSimon Schubert 
3095796c8dcSSimon Schubert   return scb;
3105796c8dcSSimon Schubert }
3115796c8dcSSimon Schubert 
312*c50c785cSJohn Marino struct serial *
313*c50c785cSJohn Marino serial_fdopen (const int fd)
314*c50c785cSJohn Marino {
315*c50c785cSJohn Marino   return serial_fdopen_ops (fd, NULL);
316*c50c785cSJohn Marino }
317*c50c785cSJohn Marino 
3185796c8dcSSimon Schubert static void
3195796c8dcSSimon Schubert do_serial_close (struct serial *scb, int really_close)
3205796c8dcSSimon Schubert {
3215796c8dcSSimon Schubert   struct serial *tmp_scb;
3225796c8dcSSimon Schubert 
3235796c8dcSSimon Schubert   last_serial_opened = NULL;
3245796c8dcSSimon Schubert 
3255796c8dcSSimon Schubert   if (serial_logfp)
3265796c8dcSSimon Schubert     {
3275796c8dcSSimon Schubert       fputs_unfiltered ("\nEnd of log\n", serial_logfp);
3285796c8dcSSimon Schubert       serial_current_type = 0;
3295796c8dcSSimon Schubert 
3305796c8dcSSimon Schubert       /* XXX - What if serial_logfp == gdb_stdout or gdb_stderr?  */
3315796c8dcSSimon Schubert       ui_file_delete (serial_logfp);
3325796c8dcSSimon Schubert       serial_logfp = NULL;
3335796c8dcSSimon Schubert     }
3345796c8dcSSimon Schubert 
3355796c8dcSSimon Schubert /* This is bogus.  It's not our fault if you pass us a bad scb...!  Rob, you
3365796c8dcSSimon Schubert    should fix your code instead.  */
3375796c8dcSSimon Schubert 
3385796c8dcSSimon Schubert   if (!scb)
3395796c8dcSSimon Schubert     return;
3405796c8dcSSimon Schubert 
3415796c8dcSSimon Schubert   scb->refcnt--;
3425796c8dcSSimon Schubert   if (scb->refcnt > 0)
3435796c8dcSSimon Schubert     return;
3445796c8dcSSimon Schubert 
345*c50c785cSJohn Marino   /* ensure that the FD has been taken out of async mode.  */
3465796c8dcSSimon Schubert   if (scb->async_handler != NULL)
3475796c8dcSSimon Schubert     serial_async (scb, NULL, NULL);
3485796c8dcSSimon Schubert 
3495796c8dcSSimon Schubert   if (really_close)
3505796c8dcSSimon Schubert     scb->ops->close (scb);
3515796c8dcSSimon Schubert 
3525796c8dcSSimon Schubert   if (scb->name)
3535796c8dcSSimon Schubert     xfree (scb->name);
3545796c8dcSSimon Schubert 
3555796c8dcSSimon Schubert   if (scb_base == scb)
3565796c8dcSSimon Schubert     scb_base = scb_base->next;
3575796c8dcSSimon Schubert   else
3585796c8dcSSimon Schubert     for (tmp_scb = scb_base; tmp_scb; tmp_scb = tmp_scb->next)
3595796c8dcSSimon Schubert       {
3605796c8dcSSimon Schubert 	if (tmp_scb->next != scb)
3615796c8dcSSimon Schubert 	  continue;
3625796c8dcSSimon Schubert 
3635796c8dcSSimon Schubert 	tmp_scb->next = tmp_scb->next->next;
3645796c8dcSSimon Schubert 	break;
3655796c8dcSSimon Schubert       }
3665796c8dcSSimon Schubert 
3675796c8dcSSimon Schubert   xfree (scb);
3685796c8dcSSimon Schubert }
3695796c8dcSSimon Schubert 
3705796c8dcSSimon Schubert void
3715796c8dcSSimon Schubert serial_close (struct serial *scb)
3725796c8dcSSimon Schubert {
3735796c8dcSSimon Schubert   do_serial_close (scb, 1);
3745796c8dcSSimon Schubert }
3755796c8dcSSimon Schubert 
3765796c8dcSSimon Schubert void
3775796c8dcSSimon Schubert serial_un_fdopen (struct serial *scb)
3785796c8dcSSimon Schubert {
3795796c8dcSSimon Schubert   do_serial_close (scb, 0);
3805796c8dcSSimon Schubert }
3815796c8dcSSimon Schubert 
3825796c8dcSSimon Schubert int
3835796c8dcSSimon Schubert serial_readchar (struct serial *scb, int timeout)
3845796c8dcSSimon Schubert {
3855796c8dcSSimon Schubert   int ch;
3865796c8dcSSimon Schubert 
3875796c8dcSSimon Schubert   /* FIXME: cagney/1999-10-11: Don't enable this check until the ASYNC
3885796c8dcSSimon Schubert      code is finished.  */
3895796c8dcSSimon Schubert   if (0 && serial_is_async_p (scb) && timeout < 0)
3905796c8dcSSimon Schubert     internal_error (__FILE__, __LINE__,
3915796c8dcSSimon Schubert 		    _("serial_readchar: blocking read in async mode"));
3925796c8dcSSimon Schubert 
3935796c8dcSSimon Schubert   ch = scb->ops->readchar (scb, timeout);
3945796c8dcSSimon Schubert   if (serial_logfp != NULL)
3955796c8dcSSimon Schubert     {
3965796c8dcSSimon Schubert       serial_logchar (serial_logfp, 'r', ch, timeout);
3975796c8dcSSimon Schubert 
3985796c8dcSSimon Schubert       /* Make sure that the log file is as up-to-date as possible,
3995796c8dcSSimon Schubert          in case we are getting ready to dump core or something.  */
4005796c8dcSSimon Schubert       gdb_flush (serial_logfp);
4015796c8dcSSimon Schubert     }
4025796c8dcSSimon Schubert   if (serial_debug_p (scb))
4035796c8dcSSimon Schubert     {
4045796c8dcSSimon Schubert       fprintf_unfiltered (gdb_stdlog, "[");
4055796c8dcSSimon Schubert       serial_logchar (gdb_stdlog, 'r', ch, timeout);
4065796c8dcSSimon Schubert       fprintf_unfiltered (gdb_stdlog, "]");
4075796c8dcSSimon Schubert       gdb_flush (gdb_stdlog);
4085796c8dcSSimon Schubert     }
4095796c8dcSSimon Schubert 
4105796c8dcSSimon Schubert   return (ch);
4115796c8dcSSimon Schubert }
4125796c8dcSSimon Schubert 
4135796c8dcSSimon Schubert int
4145796c8dcSSimon Schubert serial_write (struct serial *scb, const char *str, int len)
4155796c8dcSSimon Schubert {
4165796c8dcSSimon Schubert   if (serial_logfp != NULL)
4175796c8dcSSimon Schubert     {
4185796c8dcSSimon Schubert       int count;
4195796c8dcSSimon Schubert 
4205796c8dcSSimon Schubert       for (count = 0; count < len; count++)
4215796c8dcSSimon Schubert 	serial_logchar (serial_logfp, 'w', str[count] & 0xff, 0);
4225796c8dcSSimon Schubert 
4235796c8dcSSimon Schubert       /* Make sure that the log file is as up-to-date as possible,
4245796c8dcSSimon Schubert          in case we are getting ready to dump core or something.  */
4255796c8dcSSimon Schubert       gdb_flush (serial_logfp);
4265796c8dcSSimon Schubert     }
427cf7f2e2dSJohn Marino   if (serial_debug_p (scb))
428cf7f2e2dSJohn Marino     {
429cf7f2e2dSJohn Marino       int count;
430cf7f2e2dSJohn Marino 
431cf7f2e2dSJohn Marino       for (count = 0; count < len; count++)
432cf7f2e2dSJohn Marino 	{
433cf7f2e2dSJohn Marino 	  fprintf_unfiltered (gdb_stdlog, "[");
434cf7f2e2dSJohn Marino 	  serial_logchar (gdb_stdlog, 'w', str[count] & 0xff, 0);
435cf7f2e2dSJohn Marino 	  fprintf_unfiltered (gdb_stdlog, "]");
436cf7f2e2dSJohn Marino 	}
437cf7f2e2dSJohn Marino       gdb_flush (gdb_stdlog);
438cf7f2e2dSJohn Marino     }
4395796c8dcSSimon Schubert 
4405796c8dcSSimon Schubert   return (scb->ops->write (scb, str, len));
4415796c8dcSSimon Schubert }
4425796c8dcSSimon Schubert 
4435796c8dcSSimon Schubert void
4445796c8dcSSimon Schubert serial_printf (struct serial *desc, const char *format,...)
4455796c8dcSSimon Schubert {
4465796c8dcSSimon Schubert   va_list args;
4475796c8dcSSimon Schubert   char *buf;
4485796c8dcSSimon Schubert   va_start (args, format);
4495796c8dcSSimon Schubert 
4505796c8dcSSimon Schubert   buf = xstrvprintf (format, args);
4515796c8dcSSimon Schubert   serial_write (desc, buf, strlen (buf));
4525796c8dcSSimon Schubert 
4535796c8dcSSimon Schubert   xfree (buf);
4545796c8dcSSimon Schubert   va_end (args);
4555796c8dcSSimon Schubert }
4565796c8dcSSimon Schubert 
4575796c8dcSSimon Schubert int
4585796c8dcSSimon Schubert serial_drain_output (struct serial *scb)
4595796c8dcSSimon Schubert {
4605796c8dcSSimon Schubert   return scb->ops->drain_output (scb);
4615796c8dcSSimon Schubert }
4625796c8dcSSimon Schubert 
4635796c8dcSSimon Schubert int
4645796c8dcSSimon Schubert serial_flush_output (struct serial *scb)
4655796c8dcSSimon Schubert {
4665796c8dcSSimon Schubert   return scb->ops->flush_output (scb);
4675796c8dcSSimon Schubert }
4685796c8dcSSimon Schubert 
4695796c8dcSSimon Schubert int
4705796c8dcSSimon Schubert serial_flush_input (struct serial *scb)
4715796c8dcSSimon Schubert {
4725796c8dcSSimon Schubert   return scb->ops->flush_input (scb);
4735796c8dcSSimon Schubert }
4745796c8dcSSimon Schubert 
4755796c8dcSSimon Schubert int
4765796c8dcSSimon Schubert serial_send_break (struct serial *scb)
4775796c8dcSSimon Schubert {
4785796c8dcSSimon Schubert   if (serial_logfp != NULL)
4795796c8dcSSimon Schubert     serial_logchar (serial_logfp, 'w', SERIAL_BREAK, 0);
4805796c8dcSSimon Schubert 
4815796c8dcSSimon Schubert   return (scb->ops->send_break (scb));
4825796c8dcSSimon Schubert }
4835796c8dcSSimon Schubert 
4845796c8dcSSimon Schubert void
4855796c8dcSSimon Schubert serial_raw (struct serial *scb)
4865796c8dcSSimon Schubert {
4875796c8dcSSimon Schubert   scb->ops->go_raw (scb);
4885796c8dcSSimon Schubert }
4895796c8dcSSimon Schubert 
4905796c8dcSSimon Schubert serial_ttystate
4915796c8dcSSimon Schubert serial_get_tty_state (struct serial *scb)
4925796c8dcSSimon Schubert {
4935796c8dcSSimon Schubert   return scb->ops->get_tty_state (scb);
4945796c8dcSSimon Schubert }
4955796c8dcSSimon Schubert 
496*c50c785cSJohn Marino serial_ttystate
497*c50c785cSJohn Marino serial_copy_tty_state (struct serial *scb, serial_ttystate ttystate)
498*c50c785cSJohn Marino {
499*c50c785cSJohn Marino   return scb->ops->copy_tty_state (scb, ttystate);
500*c50c785cSJohn Marino }
501*c50c785cSJohn Marino 
5025796c8dcSSimon Schubert int
5035796c8dcSSimon Schubert serial_set_tty_state (struct serial *scb, serial_ttystate ttystate)
5045796c8dcSSimon Schubert {
5055796c8dcSSimon Schubert   return scb->ops->set_tty_state (scb, ttystate);
5065796c8dcSSimon Schubert }
5075796c8dcSSimon Schubert 
5085796c8dcSSimon Schubert void
5095796c8dcSSimon Schubert serial_print_tty_state (struct serial *scb,
5105796c8dcSSimon Schubert 			serial_ttystate ttystate,
5115796c8dcSSimon Schubert 			struct ui_file *stream)
5125796c8dcSSimon Schubert {
5135796c8dcSSimon Schubert   scb->ops->print_tty_state (scb, ttystate, stream);
5145796c8dcSSimon Schubert }
5155796c8dcSSimon Schubert 
5165796c8dcSSimon Schubert int
5175796c8dcSSimon Schubert serial_noflush_set_tty_state (struct serial *scb,
5185796c8dcSSimon Schubert 			      serial_ttystate new_ttystate,
5195796c8dcSSimon Schubert 			      serial_ttystate old_ttystate)
5205796c8dcSSimon Schubert {
5215796c8dcSSimon Schubert   return scb->ops->noflush_set_tty_state (scb, new_ttystate, old_ttystate);
5225796c8dcSSimon Schubert }
5235796c8dcSSimon Schubert 
5245796c8dcSSimon Schubert int
5255796c8dcSSimon Schubert serial_setbaudrate (struct serial *scb, int rate)
5265796c8dcSSimon Schubert {
5275796c8dcSSimon Schubert   return scb->ops->setbaudrate (scb, rate);
5285796c8dcSSimon Schubert }
5295796c8dcSSimon Schubert 
5305796c8dcSSimon Schubert int
5315796c8dcSSimon Schubert serial_setstopbits (struct serial *scb, int num)
5325796c8dcSSimon Schubert {
5335796c8dcSSimon Schubert   return scb->ops->setstopbits (scb, num);
5345796c8dcSSimon Schubert }
5355796c8dcSSimon Schubert 
5365796c8dcSSimon Schubert int
5375796c8dcSSimon Schubert serial_can_async_p (struct serial *scb)
5385796c8dcSSimon Schubert {
5395796c8dcSSimon Schubert   return (scb->ops->async != NULL);
5405796c8dcSSimon Schubert }
5415796c8dcSSimon Schubert 
5425796c8dcSSimon Schubert int
5435796c8dcSSimon Schubert serial_is_async_p (struct serial *scb)
5445796c8dcSSimon Schubert {
5455796c8dcSSimon Schubert   return (scb->ops->async != NULL) && (scb->async_handler != NULL);
5465796c8dcSSimon Schubert }
5475796c8dcSSimon Schubert 
5485796c8dcSSimon Schubert void
5495796c8dcSSimon Schubert serial_async (struct serial *scb,
5505796c8dcSSimon Schubert 	      serial_event_ftype *handler,
5515796c8dcSSimon Schubert 	      void *context)
5525796c8dcSSimon Schubert {
5535796c8dcSSimon Schubert   int changed = ((scb->async_handler == NULL) != (handler == NULL));
554cf7f2e2dSJohn Marino 
5555796c8dcSSimon Schubert   scb->async_handler = handler;
5565796c8dcSSimon Schubert   scb->async_context = context;
5575796c8dcSSimon Schubert   /* Only change mode if there is a need.  */
5585796c8dcSSimon Schubert   if (changed)
5595796c8dcSSimon Schubert     scb->ops->async (scb, handler != NULL);
5605796c8dcSSimon Schubert }
5615796c8dcSSimon Schubert 
5625796c8dcSSimon Schubert int
5635796c8dcSSimon Schubert deprecated_serial_fd (struct serial *scb)
5645796c8dcSSimon Schubert {
5655796c8dcSSimon Schubert   /* FIXME: should this output a warning that deprecated code is being
5665796c8dcSSimon Schubert      called?  */
5675796c8dcSSimon Schubert   if (scb->fd < 0)
5685796c8dcSSimon Schubert     {
5695796c8dcSSimon Schubert       internal_error (__FILE__, __LINE__,
5705796c8dcSSimon Schubert 		      _("serial: FD not valid"));
5715796c8dcSSimon Schubert     }
5725796c8dcSSimon Schubert   return scb->fd; /* sigh */
5735796c8dcSSimon Schubert }
5745796c8dcSSimon Schubert 
5755796c8dcSSimon Schubert void
5765796c8dcSSimon Schubert serial_debug (struct serial *scb, int debug_p)
5775796c8dcSSimon Schubert {
5785796c8dcSSimon Schubert   scb->debug_p = debug_p;
5795796c8dcSSimon Schubert }
5805796c8dcSSimon Schubert 
5815796c8dcSSimon Schubert int
5825796c8dcSSimon Schubert serial_debug_p (struct serial *scb)
5835796c8dcSSimon Schubert {
5845796c8dcSSimon Schubert   return scb->debug_p || global_serial_debug_p;
5855796c8dcSSimon Schubert }
5865796c8dcSSimon Schubert 
5875796c8dcSSimon Schubert #ifdef USE_WIN32API
5885796c8dcSSimon Schubert void
5895796c8dcSSimon Schubert serial_wait_handle (struct serial *scb, HANDLE *read, HANDLE *except)
5905796c8dcSSimon Schubert {
5915796c8dcSSimon Schubert   if (scb->ops->wait_handle)
5925796c8dcSSimon Schubert     scb->ops->wait_handle (scb, read, except);
5935796c8dcSSimon Schubert   else
5945796c8dcSSimon Schubert     {
5955796c8dcSSimon Schubert       *read = (HANDLE) _get_osfhandle (scb->fd);
5965796c8dcSSimon Schubert       *except = NULL;
5975796c8dcSSimon Schubert     }
5985796c8dcSSimon Schubert }
5995796c8dcSSimon Schubert 
6005796c8dcSSimon Schubert void
6015796c8dcSSimon Schubert serial_done_wait_handle (struct serial *scb)
6025796c8dcSSimon Schubert {
6035796c8dcSSimon Schubert   if (scb->ops->done_wait_handle)
6045796c8dcSSimon Schubert     scb->ops->done_wait_handle (scb);
6055796c8dcSSimon Schubert }
6065796c8dcSSimon Schubert #endif
6075796c8dcSSimon Schubert 
608*c50c785cSJohn Marino int
609*c50c785cSJohn Marino serial_pipe (struct serial *scbs[2])
610*c50c785cSJohn Marino {
611*c50c785cSJohn Marino   struct serial_ops *ops;
612*c50c785cSJohn Marino   int fildes[2];
613*c50c785cSJohn Marino 
614*c50c785cSJohn Marino   ops = serial_interface_lookup ("pipe");
615*c50c785cSJohn Marino   if (!ops)
616*c50c785cSJohn Marino     {
617*c50c785cSJohn Marino       errno = ENOSYS;
618*c50c785cSJohn Marino       return -1;
619*c50c785cSJohn Marino     }
620*c50c785cSJohn Marino 
621*c50c785cSJohn Marino   if (gdb_pipe (fildes) == -1)
622*c50c785cSJohn Marino     return -1;
623*c50c785cSJohn Marino 
624*c50c785cSJohn Marino   scbs[0] = serial_fdopen_ops (fildes[0], ops);
625*c50c785cSJohn Marino   scbs[1] = serial_fdopen_ops (fildes[1], ops);
626*c50c785cSJohn Marino   return 0;
627*c50c785cSJohn Marino }
628*c50c785cSJohn Marino 
6295796c8dcSSimon Schubert #if 0
6305796c8dcSSimon Schubert /* The connect command is #if 0 because I hadn't thought of an elegant
6315796c8dcSSimon Schubert    way to wait for I/O on two `struct serial *'s simultaneously.  Two
6325796c8dcSSimon Schubert    solutions came to mind:
6335796c8dcSSimon Schubert 
6345796c8dcSSimon Schubert    1) Fork, and have have one fork handle the to user direction,
6355796c8dcSSimon Schubert    and have the other hand the to target direction.  This
6365796c8dcSSimon Schubert    obviously won't cut it for MSDOS.
6375796c8dcSSimon Schubert 
6385796c8dcSSimon Schubert    2) Use something like select.  This assumes that stdin and
6395796c8dcSSimon Schubert    the target side can both be waited on via the same
6405796c8dcSSimon Schubert    mechanism.  This may not be true for DOS, if GDB is
6415796c8dcSSimon Schubert    talking to the target via a TCP socket.
6425796c8dcSSimon Schubert    -grossman, 8 Jun 93 */
6435796c8dcSSimon Schubert 
6445796c8dcSSimon Schubert /* Connect the user directly to the remote system.  This command acts just like
6455796c8dcSSimon Schubert    the 'cu' or 'tip' command.  Use <CR>~. or <CR>~^D to break out.  */
6465796c8dcSSimon Schubert 
6475796c8dcSSimon Schubert static struct serial *tty_desc;	/* Controlling terminal */
6485796c8dcSSimon Schubert 
6495796c8dcSSimon Schubert static void
6505796c8dcSSimon Schubert cleanup_tty (serial_ttystate ttystate)
6515796c8dcSSimon Schubert {
6525796c8dcSSimon Schubert   printf_unfiltered ("\r\n[Exiting connect mode]\r\n");
6535796c8dcSSimon Schubert   serial_set_tty_state (tty_desc, ttystate);
6545796c8dcSSimon Schubert   xfree (ttystate);
6555796c8dcSSimon Schubert   serial_close (tty_desc);
6565796c8dcSSimon Schubert }
6575796c8dcSSimon Schubert 
6585796c8dcSSimon Schubert static void
6595796c8dcSSimon Schubert connect_command (char *args, int fromtty)
6605796c8dcSSimon Schubert {
6615796c8dcSSimon Schubert   int c;
6625796c8dcSSimon Schubert   char cur_esc = 0;
6635796c8dcSSimon Schubert   serial_ttystate ttystate;
6645796c8dcSSimon Schubert   struct serial *port_desc;		/* TTY port */
6655796c8dcSSimon Schubert 
6665796c8dcSSimon Schubert   dont_repeat ();
6675796c8dcSSimon Schubert 
6685796c8dcSSimon Schubert   if (args)
669*c50c785cSJohn Marino     fprintf_unfiltered (gdb_stderr,
670*c50c785cSJohn Marino 			"This command takes no args.  "
671*c50c785cSJohn Marino 			"They have been ignored.\n");
6725796c8dcSSimon Schubert 
6735796c8dcSSimon Schubert   printf_unfiltered ("[Entering connect mode.  Use ~. or ~^D to escape]\n");
6745796c8dcSSimon Schubert 
6755796c8dcSSimon Schubert   tty_desc = serial_fdopen (0);
6765796c8dcSSimon Schubert   port_desc = last_serial_opened;
6775796c8dcSSimon Schubert 
6785796c8dcSSimon Schubert   ttystate = serial_get_tty_state (tty_desc);
6795796c8dcSSimon Schubert 
6805796c8dcSSimon Schubert   serial_raw (tty_desc);
6815796c8dcSSimon Schubert   serial_raw (port_desc);
6825796c8dcSSimon Schubert 
6835796c8dcSSimon Schubert   make_cleanup (cleanup_tty, ttystate);
6845796c8dcSSimon Schubert 
6855796c8dcSSimon Schubert   while (1)
6865796c8dcSSimon Schubert     {
6875796c8dcSSimon Schubert       int mask;
6885796c8dcSSimon Schubert 
6895796c8dcSSimon Schubert       mask = serial_wait_2 (tty_desc, port_desc, -1);
6905796c8dcSSimon Schubert 
6915796c8dcSSimon Schubert       if (mask & 2)
6925796c8dcSSimon Schubert 	{			/* tty input */
6935796c8dcSSimon Schubert 	  char cx;
6945796c8dcSSimon Schubert 
6955796c8dcSSimon Schubert 	  while (1)
6965796c8dcSSimon Schubert 	    {
6975796c8dcSSimon Schubert 	      c = serial_readchar (tty_desc, 0);
6985796c8dcSSimon Schubert 
6995796c8dcSSimon Schubert 	      if (c == SERIAL_TIMEOUT)
7005796c8dcSSimon Schubert 		break;
7015796c8dcSSimon Schubert 
7025796c8dcSSimon Schubert 	      if (c < 0)
7035796c8dcSSimon Schubert 		perror_with_name (_("connect"));
7045796c8dcSSimon Schubert 
7055796c8dcSSimon Schubert 	      cx = c;
7065796c8dcSSimon Schubert 	      serial_write (port_desc, &cx, 1);
7075796c8dcSSimon Schubert 
7085796c8dcSSimon Schubert 	      switch (cur_esc)
7095796c8dcSSimon Schubert 		{
7105796c8dcSSimon Schubert 		case 0:
7115796c8dcSSimon Schubert 		  if (c == '\r')
7125796c8dcSSimon Schubert 		    cur_esc = c;
7135796c8dcSSimon Schubert 		  break;
7145796c8dcSSimon Schubert 		case '\r':
7155796c8dcSSimon Schubert 		  if (c == '~')
7165796c8dcSSimon Schubert 		    cur_esc = c;
7175796c8dcSSimon Schubert 		  else
7185796c8dcSSimon Schubert 		    cur_esc = 0;
7195796c8dcSSimon Schubert 		  break;
7205796c8dcSSimon Schubert 		case '~':
7215796c8dcSSimon Schubert 		  if (c == '.' || c == '\004')
7225796c8dcSSimon Schubert 		    return;
7235796c8dcSSimon Schubert 		  else
7245796c8dcSSimon Schubert 		    cur_esc = 0;
7255796c8dcSSimon Schubert 		}
7265796c8dcSSimon Schubert 	    }
7275796c8dcSSimon Schubert 	}
7285796c8dcSSimon Schubert 
7295796c8dcSSimon Schubert       if (mask & 1)
7305796c8dcSSimon Schubert 	{			/* Port input */
7315796c8dcSSimon Schubert 	  char cx;
7325796c8dcSSimon Schubert 
7335796c8dcSSimon Schubert 	  while (1)
7345796c8dcSSimon Schubert 	    {
7355796c8dcSSimon Schubert 	      c = serial_readchar (port_desc, 0);
7365796c8dcSSimon Schubert 
7375796c8dcSSimon Schubert 	      if (c == SERIAL_TIMEOUT)
7385796c8dcSSimon Schubert 		break;
7395796c8dcSSimon Schubert 
7405796c8dcSSimon Schubert 	      if (c < 0)
7415796c8dcSSimon Schubert 		perror_with_name (_("connect"));
7425796c8dcSSimon Schubert 
7435796c8dcSSimon Schubert 	      cx = c;
7445796c8dcSSimon Schubert 
7455796c8dcSSimon Schubert 	      serial_write (tty_desc, &cx, 1);
7465796c8dcSSimon Schubert 	    }
7475796c8dcSSimon Schubert 	}
7485796c8dcSSimon Schubert     }
7495796c8dcSSimon Schubert }
7505796c8dcSSimon Schubert #endif /* 0 */
7515796c8dcSSimon Schubert 
7525796c8dcSSimon Schubert /* Serial set/show framework.  */
7535796c8dcSSimon Schubert 
7545796c8dcSSimon Schubert static struct cmd_list_element *serial_set_cmdlist;
7555796c8dcSSimon Schubert static struct cmd_list_element *serial_show_cmdlist;
7565796c8dcSSimon Schubert 
7575796c8dcSSimon Schubert static void
7585796c8dcSSimon Schubert serial_set_cmd (char *args, int from_tty)
7595796c8dcSSimon Schubert {
760*c50c785cSJohn Marino   printf_unfiltered ("\"set serial\" must be followed "
761*c50c785cSJohn Marino 		     "by the name of a command.\n");
7625796c8dcSSimon Schubert   help_list (serial_set_cmdlist, "set serial ", -1, gdb_stdout);
7635796c8dcSSimon Schubert }
7645796c8dcSSimon Schubert 
7655796c8dcSSimon Schubert static void
7665796c8dcSSimon Schubert serial_show_cmd (char *args, int from_tty)
7675796c8dcSSimon Schubert {
7685796c8dcSSimon Schubert   cmd_show_list (serial_show_cmdlist, from_tty, "");
7695796c8dcSSimon Schubert }
7705796c8dcSSimon Schubert 
7715796c8dcSSimon Schubert 
7725796c8dcSSimon Schubert void
7735796c8dcSSimon Schubert _initialize_serial (void)
7745796c8dcSSimon Schubert {
7755796c8dcSSimon Schubert #if 0
7765796c8dcSSimon Schubert   add_com ("connect", class_obscure, connect_command, _("\
7775796c8dcSSimon Schubert Connect the terminal directly up to the command monitor.\n\
7785796c8dcSSimon Schubert Use <CR>~. or <CR>~^D to break out."));
7795796c8dcSSimon Schubert #endif /* 0 */
7805796c8dcSSimon Schubert 
7815796c8dcSSimon Schubert   add_prefix_cmd ("serial", class_maintenance, serial_set_cmd, _("\
7825796c8dcSSimon Schubert Set default serial/parallel port configuration."),
7835796c8dcSSimon Schubert 		  &serial_set_cmdlist, "set serial ",
7845796c8dcSSimon Schubert 		  0/*allow-unknown*/,
7855796c8dcSSimon Schubert 		  &setlist);
7865796c8dcSSimon Schubert 
7875796c8dcSSimon Schubert   add_prefix_cmd ("serial", class_maintenance, serial_show_cmd, _("\
7885796c8dcSSimon Schubert Show default serial/parallel port configuration."),
7895796c8dcSSimon Schubert 		  &serial_show_cmdlist, "show serial ",
7905796c8dcSSimon Schubert 		  0/*allow-unknown*/,
7915796c8dcSSimon Schubert 		  &showlist);
7925796c8dcSSimon Schubert 
7935796c8dcSSimon Schubert   add_setshow_filename_cmd ("remotelogfile", no_class, &serial_logfile, _("\
7945796c8dcSSimon Schubert Set filename for remote session recording."), _("\
7955796c8dcSSimon Schubert Show filename for remote session recording."), _("\
7965796c8dcSSimon Schubert This file is used to record the remote session for future playback\n\
7975796c8dcSSimon Schubert by gdbserver."),
7985796c8dcSSimon Schubert 			    NULL,
7995796c8dcSSimon Schubert 			    NULL, /* FIXME: i18n: */
8005796c8dcSSimon Schubert 			    &setlist, &showlist);
8015796c8dcSSimon Schubert 
8025796c8dcSSimon Schubert   add_setshow_enum_cmd ("remotelogbase", no_class, logbase_enums,
8035796c8dcSSimon Schubert 			&serial_logbase, _("\
8045796c8dcSSimon Schubert Set numerical base for remote session logging"), _("\
8055796c8dcSSimon Schubert Show numerical base for remote session logging"), NULL,
8065796c8dcSSimon Schubert 			NULL,
8075796c8dcSSimon Schubert 			NULL, /* FIXME: i18n: */
8085796c8dcSSimon Schubert 			&setlist, &showlist);
8095796c8dcSSimon Schubert 
8105796c8dcSSimon Schubert   add_setshow_zinteger_cmd ("serial", class_maintenance,
8115796c8dcSSimon Schubert 			    &global_serial_debug_p, _("\
8125796c8dcSSimon Schubert Set serial debugging."), _("\
8135796c8dcSSimon Schubert Show serial debugging."), _("\
8145796c8dcSSimon Schubert When non-zero, serial port debugging is enabled."),
8155796c8dcSSimon Schubert 			    NULL,
8165796c8dcSSimon Schubert 			    NULL, /* FIXME: i18n: */
8175796c8dcSSimon Schubert 			    &setdebuglist, &showdebuglist);
8185796c8dcSSimon Schubert }
819