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