GDB (API)
/home/stan/gdb/src/gdb/serial.c
Go to the documentation of this file.
00001 /* Generic serial interface routines
00002 
00003    Copyright (C) 1992-2013 Free Software Foundation, Inc.
00004 
00005    This file is part of GDB.
00006 
00007    This program is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License as published by
00009    the Free Software Foundation; either version 3 of the License, or
00010    (at your option) any later version.
00011 
00012    This program is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015    GNU General Public License for more details.
00016 
00017    You should have received a copy of the GNU General Public License
00018    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
00019 
00020 #include "defs.h"
00021 #include <ctype.h>
00022 #include "serial.h"
00023 #include "gdb_string.h"
00024 #include "gdbcmd.h"
00025 #include "cli/cli-utils.h"
00026 
00027 extern void _initialize_serial (void);
00028 
00029 /* Is serial being debugged?  */
00030 
00031 static unsigned int global_serial_debug_p;
00032 
00033 /* Linked list of serial I/O handlers.  */
00034 
00035 static struct serial_ops *serial_ops_list = NULL;
00036 
00037 /* Pointer to list of scb's.  */
00038 
00039 static struct serial *scb_base;
00040 
00041 /* Non-NULL gives filename which contains a recording of the remote session,
00042    suitable for playback by gdbserver.  */
00043 
00044 static char *serial_logfile = NULL;
00045 static struct ui_file *serial_logfp = NULL;
00046 
00047 static struct serial_ops *serial_interface_lookup (const char *);
00048 static void serial_logchar (struct ui_file *stream,
00049                             int ch_type, int ch, int timeout);
00050 static const char logbase_hex[] = "hex";
00051 static const char logbase_octal[] = "octal";
00052 static const char logbase_ascii[] = "ascii";
00053 static const char *const logbase_enums[] =
00054 {logbase_hex, logbase_octal, logbase_ascii, NULL};
00055 static const char *serial_logbase = logbase_ascii;
00056 
00057 
00058 static int serial_current_type = 0;
00059 
00060 /* Log char CH of type CHTYPE, with TIMEOUT.  */
00061 
00062 /* Define bogus char to represent a BREAK.  Should be careful to choose a value
00063    that can't be confused with a normal char, or an error code.  */
00064 #define SERIAL_BREAK 1235
00065 
00066 static void
00067 serial_logchar (struct ui_file *stream, int ch_type, int ch, int timeout)
00068 {
00069   if (ch_type != serial_current_type)
00070     {
00071       fprintf_unfiltered (stream, "\n%c ", ch_type);
00072       serial_current_type = ch_type;
00073     }
00074 
00075   if (serial_logbase != logbase_ascii)
00076     fputc_unfiltered (' ', stream);
00077 
00078   switch (ch)
00079     {
00080     case SERIAL_TIMEOUT:
00081       fprintf_unfiltered (stream, "<Timeout: %d seconds>", timeout);
00082       return;
00083     case SERIAL_ERROR:
00084       fprintf_unfiltered (stream, "<Error: %s>", safe_strerror (errno));
00085       return;
00086     case SERIAL_EOF:
00087       fputs_unfiltered ("<Eof>", stream);
00088       return;
00089     case SERIAL_BREAK:
00090       fputs_unfiltered ("<Break>", stream);
00091       return;
00092     default:
00093       if (serial_logbase == logbase_hex)
00094         fprintf_unfiltered (stream, "%02x", ch & 0xff);
00095       else if (serial_logbase == logbase_octal)
00096         fprintf_unfiltered (stream, "%03o", ch & 0xff);
00097       else
00098         switch (ch)
00099           {
00100           case '\\':
00101             fputs_unfiltered ("\\\\", stream);
00102             break;
00103           case '\b':
00104             fputs_unfiltered ("\\b", stream);
00105             break;
00106           case '\f':
00107             fputs_unfiltered ("\\f", stream);
00108             break;
00109           case '\n':
00110             fputs_unfiltered ("\\n", stream);
00111             break;
00112           case '\r':
00113             fputs_unfiltered ("\\r", stream);
00114             break;
00115           case '\t':
00116             fputs_unfiltered ("\\t", stream);
00117             break;
00118           case '\v':
00119             fputs_unfiltered ("\\v", stream);
00120             break;
00121           default:
00122             fprintf_unfiltered (stream,
00123                                 isprint (ch) ? "%c" : "\\x%02x", ch & 0xFF);
00124             break;
00125           }
00126     }
00127 }
00128 
00129 void
00130 serial_log_command (const char *cmd)
00131 {
00132   if (!serial_logfp)
00133     return;
00134 
00135   serial_current_type = 'c';
00136 
00137   fputs_unfiltered ("\nc ", serial_logfp);
00138   fputs_unfiltered (cmd, serial_logfp);
00139 
00140   /* Make sure that the log file is as up-to-date as possible,
00141      in case we are getting ready to dump core or something.  */
00142   gdb_flush (serial_logfp);
00143 }
00144 
00145 
00146 static struct serial_ops *
00147 serial_interface_lookup (const char *name)
00148 {
00149   struct serial_ops *ops;
00150 
00151   for (ops = serial_ops_list; ops; ops = ops->next)
00152     if (strcmp (name, ops->name) == 0)
00153       return ops;
00154 
00155   return NULL;
00156 }
00157 
00158 void
00159 serial_add_interface (struct serial_ops *optable)
00160 {
00161   optable->next = serial_ops_list;
00162   serial_ops_list = optable;
00163 }
00164 
00165 /* Return the open serial device for FD, if found, or NULL if FD is
00166    not already opened.  */
00167 
00168 struct serial *
00169 serial_for_fd (int fd)
00170 {
00171   struct serial *scb;
00172 
00173   for (scb = scb_base; scb; scb = scb->next)
00174     if (scb->fd == fd)
00175       return scb;
00176 
00177   return NULL;
00178 }
00179 
00180 /* Open up a device or a network socket, depending upon the syntax of NAME.  */
00181 
00182 struct serial *
00183 serial_open (const char *name)
00184 {
00185   struct serial *scb;
00186   struct serial_ops *ops;
00187   const char *open_name = name;
00188 
00189   if (strcmp (name, "pc") == 0)
00190     ops = serial_interface_lookup ("pc");
00191   else if (strncmp (name, "lpt", 3) == 0)
00192     ops = serial_interface_lookup ("parallel");
00193   else if (strncmp (name, "|", 1) == 0)
00194     {
00195       ops = serial_interface_lookup ("pipe");
00196       /* Discard ``|'' and any space before the command itself.  */
00197       ++open_name;
00198       open_name = skip_spaces_const (open_name);
00199     }
00200   /* Check for a colon, suggesting an IP address/port pair.
00201      Do this *after* checking for all the interesting prefixes.  We
00202      don't want to constrain the syntax of what can follow them.  */
00203   else if (strchr (name, ':'))
00204     ops = serial_interface_lookup ("tcp");
00205   else
00206     ops = serial_interface_lookup ("hardwire");
00207 
00208   if (!ops)
00209     return NULL;
00210 
00211   scb = XMALLOC (struct serial);
00212 
00213   scb->ops = ops;
00214 
00215   scb->bufcnt = 0;
00216   scb->bufp = scb->buf;
00217   scb->error_fd = -1;
00218   scb->refcnt = 1;
00219 
00220   /* `...->open (...)' would get expanded by the open(2) syscall macro.  */
00221   if ((*scb->ops->open) (scb, open_name))
00222     {
00223       xfree (scb);
00224       return NULL;
00225     }
00226 
00227   scb->name = xstrdup (name);
00228   scb->next = scb_base;
00229   scb->debug_p = 0;
00230   scb->async_state = 0;
00231   scb->async_handler = NULL;
00232   scb->async_context = NULL;
00233   scb_base = scb;
00234 
00235   if (serial_logfile != NULL)
00236     {
00237       serial_logfp = gdb_fopen (serial_logfile, "w");
00238       if (serial_logfp == NULL)
00239         perror_with_name (serial_logfile);
00240     }
00241 
00242   return scb;
00243 }
00244 
00245 /* Open a new serial stream using a file handle, using serial
00246    interface ops OPS.  */
00247 
00248 static struct serial *
00249 serial_fdopen_ops (const int fd, struct serial_ops *ops)
00250 {
00251   struct serial *scb;
00252 
00253   if (!ops)
00254     {
00255       ops = serial_interface_lookup ("terminal");
00256       if (!ops)
00257         ops = serial_interface_lookup ("hardwire");
00258     }
00259 
00260   if (!ops)
00261     return NULL;
00262 
00263   scb = XCALLOC (1, struct serial);
00264 
00265   scb->ops = ops;
00266 
00267   scb->bufcnt = 0;
00268   scb->bufp = scb->buf;
00269   scb->error_fd = -1;
00270   scb->refcnt = 1;
00271 
00272   scb->name = NULL;
00273   scb->next = scb_base;
00274   scb->debug_p = 0;
00275   scb->async_state = 0;
00276   scb->async_handler = NULL;
00277   scb->async_context = NULL;
00278   scb_base = scb;
00279 
00280   if ((ops->fdopen) != NULL)
00281     (*ops->fdopen) (scb, fd);
00282   else
00283     scb->fd = fd;
00284 
00285   return scb;
00286 }
00287 
00288 struct serial *
00289 serial_fdopen (const int fd)
00290 {
00291   return serial_fdopen_ops (fd, NULL);
00292 }
00293 
00294 static void
00295 do_serial_close (struct serial *scb, int really_close)
00296 {
00297   struct serial *tmp_scb;
00298 
00299   if (serial_logfp)
00300     {
00301       fputs_unfiltered ("\nEnd of log\n", serial_logfp);
00302       serial_current_type = 0;
00303 
00304       /* XXX - What if serial_logfp == gdb_stdout or gdb_stderr?  */
00305       ui_file_delete (serial_logfp);
00306       serial_logfp = NULL;
00307     }
00308 
00309   /* ensure that the FD has been taken out of async mode.  */
00310   if (scb->async_handler != NULL)
00311     serial_async (scb, NULL, NULL);
00312 
00313   if (really_close)
00314     scb->ops->close (scb);
00315 
00316   if (scb->name)
00317     xfree (scb->name);
00318 
00319   /* For serial_is_open.  */
00320   scb->bufp = NULL;
00321 
00322   if (scb_base == scb)
00323     scb_base = scb_base->next;
00324   else
00325     for (tmp_scb = scb_base; tmp_scb; tmp_scb = tmp_scb->next)
00326       {
00327         if (tmp_scb->next != scb)
00328           continue;
00329 
00330         tmp_scb->next = tmp_scb->next->next;
00331         break;
00332       }
00333 
00334   serial_unref (scb);
00335 }
00336 
00337 void
00338 serial_close (struct serial *scb)
00339 {
00340   do_serial_close (scb, 1);
00341 }
00342 
00343 void
00344 serial_un_fdopen (struct serial *scb)
00345 {
00346   do_serial_close (scb, 0);
00347 }
00348 
00349 int
00350 serial_is_open (struct serial *scb)
00351 {
00352   return scb->bufp != NULL;
00353 }
00354 
00355 void
00356 serial_ref (struct serial *scb)
00357 {
00358   scb->refcnt++;
00359 }
00360 
00361 void
00362 serial_unref (struct serial *scb)
00363 {
00364   --scb->refcnt;
00365   if (scb->refcnt == 0)
00366     xfree (scb);
00367 }
00368 
00369 int
00370 serial_readchar (struct serial *scb, int timeout)
00371 {
00372   int ch;
00373 
00374   /* FIXME: cagney/1999-10-11: Don't enable this check until the ASYNC
00375      code is finished.  */
00376   if (0 && serial_is_async_p (scb) && timeout < 0)
00377     internal_error (__FILE__, __LINE__,
00378                     _("serial_readchar: blocking read in async mode"));
00379 
00380   ch = scb->ops->readchar (scb, timeout);
00381   if (serial_logfp != NULL)
00382     {
00383       serial_logchar (serial_logfp, 'r', ch, timeout);
00384 
00385       /* Make sure that the log file is as up-to-date as possible,
00386          in case we are getting ready to dump core or something.  */
00387       gdb_flush (serial_logfp);
00388     }
00389   if (serial_debug_p (scb))
00390     {
00391       fprintf_unfiltered (gdb_stdlog, "[");
00392       serial_logchar (gdb_stdlog, 'r', ch, timeout);
00393       fprintf_unfiltered (gdb_stdlog, "]");
00394       gdb_flush (gdb_stdlog);
00395     }
00396 
00397   return (ch);
00398 }
00399 
00400 int
00401 serial_write (struct serial *scb, const void *buf, size_t count)
00402 {
00403   if (serial_logfp != NULL)
00404     {
00405       const char *str = buf;
00406       size_t c;
00407 
00408       for (c = 0; c < count; c++)
00409         serial_logchar (serial_logfp, 'w', str[c] & 0xff, 0);
00410 
00411       /* Make sure that the log file is as up-to-date as possible,
00412          in case we are getting ready to dump core or something.  */
00413       gdb_flush (serial_logfp);
00414     }
00415   if (serial_debug_p (scb))
00416     {
00417       const char *str = buf;
00418       size_t c;
00419 
00420       for (c = 0; c < count; c++)
00421         {
00422           fprintf_unfiltered (gdb_stdlog, "[");
00423           serial_logchar (gdb_stdlog, 'w', str[count] & 0xff, 0);
00424           fprintf_unfiltered (gdb_stdlog, "]");
00425         }
00426       gdb_flush (gdb_stdlog);
00427     }
00428 
00429   return (scb->ops->write (scb, buf, count));
00430 }
00431 
00432 void
00433 serial_printf (struct serial *desc, const char *format,...)
00434 {
00435   va_list args;
00436   char *buf;
00437   va_start (args, format);
00438 
00439   buf = xstrvprintf (format, args);
00440   serial_write (desc, buf, strlen (buf));
00441 
00442   xfree (buf);
00443   va_end (args);
00444 }
00445 
00446 int
00447 serial_drain_output (struct serial *scb)
00448 {
00449   return scb->ops->drain_output (scb);
00450 }
00451 
00452 int
00453 serial_flush_output (struct serial *scb)
00454 {
00455   return scb->ops->flush_output (scb);
00456 }
00457 
00458 int
00459 serial_flush_input (struct serial *scb)
00460 {
00461   return scb->ops->flush_input (scb);
00462 }
00463 
00464 int
00465 serial_send_break (struct serial *scb)
00466 {
00467   if (serial_logfp != NULL)
00468     serial_logchar (serial_logfp, 'w', SERIAL_BREAK, 0);
00469 
00470   return (scb->ops->send_break (scb));
00471 }
00472 
00473 void
00474 serial_raw (struct serial *scb)
00475 {
00476   scb->ops->go_raw (scb);
00477 }
00478 
00479 serial_ttystate
00480 serial_get_tty_state (struct serial *scb)
00481 {
00482   return scb->ops->get_tty_state (scb);
00483 }
00484 
00485 serial_ttystate
00486 serial_copy_tty_state (struct serial *scb, serial_ttystate ttystate)
00487 {
00488   return scb->ops->copy_tty_state (scb, ttystate);
00489 }
00490 
00491 int
00492 serial_set_tty_state (struct serial *scb, serial_ttystate ttystate)
00493 {
00494   return scb->ops->set_tty_state (scb, ttystate);
00495 }
00496 
00497 void
00498 serial_print_tty_state (struct serial *scb,
00499                         serial_ttystate ttystate,
00500                         struct ui_file *stream)
00501 {
00502   scb->ops->print_tty_state (scb, ttystate, stream);
00503 }
00504 
00505 int
00506 serial_noflush_set_tty_state (struct serial *scb,
00507                               serial_ttystate new_ttystate,
00508                               serial_ttystate old_ttystate)
00509 {
00510   return scb->ops->noflush_set_tty_state (scb, new_ttystate, old_ttystate);
00511 }
00512 
00513 int
00514 serial_setbaudrate (struct serial *scb, int rate)
00515 {
00516   return scb->ops->setbaudrate (scb, rate);
00517 }
00518 
00519 int
00520 serial_setstopbits (struct serial *scb, int num)
00521 {
00522   return scb->ops->setstopbits (scb, num);
00523 }
00524 
00525 int
00526 serial_can_async_p (struct serial *scb)
00527 {
00528   return (scb->ops->async != NULL);
00529 }
00530 
00531 int
00532 serial_is_async_p (struct serial *scb)
00533 {
00534   return (scb->ops->async != NULL) && (scb->async_handler != NULL);
00535 }
00536 
00537 void
00538 serial_async (struct serial *scb,
00539               serial_event_ftype *handler,
00540               void *context)
00541 {
00542   int changed = ((scb->async_handler == NULL) != (handler == NULL));
00543 
00544   scb->async_handler = handler;
00545   scb->async_context = context;
00546   /* Only change mode if there is a need.  */
00547   if (changed)
00548     scb->ops->async (scb, handler != NULL);
00549 }
00550 
00551 void
00552 serial_debug (struct serial *scb, int debug_p)
00553 {
00554   scb->debug_p = debug_p;
00555 }
00556 
00557 int
00558 serial_debug_p (struct serial *scb)
00559 {
00560   return scb->debug_p || global_serial_debug_p;
00561 }
00562 
00563 #ifdef USE_WIN32API
00564 void
00565 serial_wait_handle (struct serial *scb, HANDLE *read, HANDLE *except)
00566 {
00567   if (scb->ops->wait_handle)
00568     scb->ops->wait_handle (scb, read, except);
00569   else
00570     {
00571       *read = (HANDLE) _get_osfhandle (scb->fd);
00572       *except = NULL;
00573     }
00574 }
00575 
00576 void
00577 serial_done_wait_handle (struct serial *scb)
00578 {
00579   if (scb->ops->done_wait_handle)
00580     scb->ops->done_wait_handle (scb);
00581 }
00582 #endif
00583 
00584 int
00585 serial_pipe (struct serial *scbs[2])
00586 {
00587   struct serial_ops *ops;
00588   int fildes[2];
00589 
00590   ops = serial_interface_lookup ("pipe");
00591   if (!ops)
00592     {
00593       errno = ENOSYS;
00594       return -1;
00595     }
00596 
00597   if (gdb_pipe (fildes) == -1)
00598     return -1;
00599 
00600   scbs[0] = serial_fdopen_ops (fildes[0], ops);
00601   scbs[1] = serial_fdopen_ops (fildes[1], ops);
00602   return 0;
00603 }
00604 
00605 /* Serial set/show framework.  */
00606 
00607 static struct cmd_list_element *serial_set_cmdlist;
00608 static struct cmd_list_element *serial_show_cmdlist;
00609 
00610 static void
00611 serial_set_cmd (char *args, int from_tty)
00612 {
00613   printf_unfiltered ("\"set serial\" must be followed "
00614                      "by the name of a command.\n");
00615   help_list (serial_set_cmdlist, "set serial ", -1, gdb_stdout);
00616 }
00617 
00618 static void
00619 serial_show_cmd (char *args, int from_tty)
00620 {
00621   cmd_show_list (serial_show_cmdlist, from_tty, "");
00622 }
00623 
00624 /* Baud rate specified for talking to serial target systems.  Default
00625    is left as -1, so targets can choose their own defaults.  */
00626 /* FIXME: This means that "show serial baud" and gr_files_info can
00627    print -1 or (unsigned int)-1.  This is a Bad User Interface.  */
00628 
00629 int baud_rate = -1;
00630 
00631 static void
00632 serial_baud_show_cmd (struct ui_file *file, int from_tty,
00633                       struct cmd_list_element *c, const char *value)
00634 {
00635   fprintf_filtered (file, _("Baud rate for remote serial I/O is %s.\n"),
00636                     value);
00637 }
00638 
00639 void
00640 _initialize_serial (void)
00641 {
00642 #if 0
00643   add_com ("connect", class_obscure, connect_command, _("\
00644 Connect the terminal directly up to the command monitor.\n\
00645 Use <CR>~. or <CR>~^D to break out."));
00646 #endif /* 0 */
00647 
00648   add_prefix_cmd ("serial", class_maintenance, serial_set_cmd, _("\
00649 Set default serial/parallel port configuration."),
00650                   &serial_set_cmdlist, "set serial ",
00651                   0/*allow-unknown*/,
00652                   &setlist);
00653 
00654   add_prefix_cmd ("serial", class_maintenance, serial_show_cmd, _("\
00655 Show default serial/parallel port configuration."),
00656                   &serial_show_cmdlist, "show serial ",
00657                   0/*allow-unknown*/,
00658                   &showlist);
00659 
00660   /* If target is open when baud changes, it doesn't take effect until
00661      the next open (I think, not sure).  */
00662   add_setshow_zinteger_cmd ("baud", no_class, &baud_rate, _("\
00663 Set baud rate for remote serial I/O."), _("\
00664 Show baud rate for remote serial I/O."), _("\
00665 This value is used to set the speed of the serial port when debugging\n\
00666 using remote targets."),
00667                             NULL,
00668                             serial_baud_show_cmd,
00669                             &serial_set_cmdlist, &serial_show_cmdlist);
00670 
00671   /* The commands "set/show serial baud" used to have a different name.
00672      Add aliases to those names to facilitate the transition, and mark
00673      them as deprecated, in order to make users aware of the fact that
00674      the command names have been changed.  */
00675     {
00676       const char *cmd_name;
00677       struct cmd_list_element *cmd;
00678 
00679       /* FIXME: There is a limitation in the deprecation mechanism,
00680          and the warning ends up not being displayed for prefixed
00681          aliases.  So use a real command instead of an alias.  */
00682       add_setshow_zinteger_cmd ("remotebaud", class_alias, &baud_rate, _("\
00683 Set baud rate for remote serial I/O."), _("\
00684 Show baud rate for remote serial I/O."), _("\
00685 This value is used to set the speed of the serial port when debugging\n\
00686 using remote targets."),
00687                                 NULL,
00688                                 serial_baud_show_cmd,
00689                                 &setlist, &showlist);
00690       cmd_name = "remotebaud";
00691       cmd = lookup_cmd (&cmd_name, setlist, "", -1, 1);
00692       deprecate_cmd (cmd, "set serial baud");
00693       cmd_name
00694         = "remotebaud"; /* needed because lookup_cmd updates the pointer */
00695       cmd = lookup_cmd (&cmd_name, showlist, "", -1, 1);
00696       deprecate_cmd (cmd, "show serial baud");
00697     }
00698 
00699   add_setshow_filename_cmd ("remotelogfile", no_class, &serial_logfile, _("\
00700 Set filename for remote session recording."), _("\
00701 Show filename for remote session recording."), _("\
00702 This file is used to record the remote session for future playback\n\
00703 by gdbserver."),
00704                             NULL,
00705                             NULL, /* FIXME: i18n: */
00706                             &setlist, &showlist);
00707 
00708   add_setshow_enum_cmd ("remotelogbase", no_class, logbase_enums,
00709                         &serial_logbase, _("\
00710 Set numerical base for remote session logging"), _("\
00711 Show numerical base for remote session logging"), NULL,
00712                         NULL,
00713                         NULL, /* FIXME: i18n: */
00714                         &setlist, &showlist);
00715 
00716   add_setshow_zuinteger_cmd ("serial", class_maintenance,
00717                              &global_serial_debug_p, _("\
00718 Set serial debugging."), _("\
00719 Show serial debugging."), _("\
00720 When non-zero, serial port debugging is enabled."),
00721                              NULL,
00722                              NULL, /* FIXME: i18n: */
00723                              &setdebuglist, &showdebuglist);
00724 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines