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