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