This commit was generated by cvs2svn to track changes on a CVS vendor
[external/binutils.git] / gdb / serial.c
1 /* Generic serial interface routines
2
3    Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
4    2001, 2002, 2004, 2005, 2006 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., 51 Franklin Street, Fifth Floor,
21    Boston, MA 02110-1301, 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 \f
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
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
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 \f
150 static struct serial_ops *
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
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 *
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 (strncmp (name, "lpt", 3) == 0)
188     ops = serial_interface_lookup ("parallel");
189   else if (strncmp (name, "|", 1) == 0)
190     {
191       ops = serial_interface_lookup ("pipe");
192       open_name = name + 1; /* discard ``|'' */
193     }
194   /* Check for a colon, suggesting an IP address/port pair.
195      Do this *after* checking for all the interesting prefixes.  We
196      don't want to constrain the syntax of what can follow them.  */
197   else if (strchr (name, ':'))
198     ops = serial_interface_lookup ("tcp");
199   else
200     ops = serial_interface_lookup ("hardwire");
201
202   if (!ops)
203     return NULL;
204
205   scb = XMALLOC (struct serial);
206
207   scb->ops = ops;
208
209   scb->bufcnt = 0;
210   scb->bufp = scb->buf;
211
212   if (scb->ops->open (scb, open_name))
213     {
214       xfree (scb);
215       return NULL;
216     }
217
218   scb->name = xstrdup (name);
219   scb->next = scb_base;
220   scb->refcnt = 1;
221   scb->debug_p = 0;
222   scb->async_state = 0;
223   scb->async_handler = NULL;
224   scb->async_context = NULL;
225   scb_base = scb;
226
227   last_serial_opened = scb;
228
229   if (serial_logfile != NULL)
230     {
231       serial_logfp = gdb_fopen (serial_logfile, "w");
232       if (serial_logfp == NULL)
233         perror_with_name (serial_logfile);
234     }
235
236   return scb;
237 }
238
239 /* Return the open serial device for FD, if found, or NULL if FD
240    is not already opened.  */
241
242 struct serial *
243 serial_for_fd (int fd)
244 {
245   struct serial *scb;
246   struct serial_ops *ops;
247
248   for (scb = scb_base; scb; scb = scb->next)
249     if (scb->fd == fd)
250       return scb;
251
252   return NULL;
253 }
254
255 struct serial *
256 serial_fdopen (const int fd)
257 {
258   struct serial *scb;
259   struct serial_ops *ops;
260
261   for (scb = scb_base; scb; scb = scb->next)
262     if (scb->fd == fd)
263       {
264         scb->refcnt++;
265         return scb;
266       }
267
268   ops = serial_interface_lookup ("terminal");
269   if (!ops)
270     ops = serial_interface_lookup ("hardwire");
271
272   if (!ops)
273     return NULL;
274
275   scb = XCALLOC (1, struct serial);
276
277   scb->ops = ops;
278
279   scb->bufcnt = 0;
280   scb->bufp = scb->buf;
281
282   scb->fd = fd;
283
284   scb->name = NULL;
285   scb->next = scb_base;
286   scb->refcnt = 1;
287   scb->debug_p = 0;
288   scb->async_state = 0;
289   scb->async_handler = NULL;
290   scb->async_context = NULL;
291   scb_base = scb;
292
293   last_serial_opened = scb;
294
295   return scb;
296 }
297
298 static void
299 do_serial_close (struct serial *scb, int really_close)
300 {
301   struct serial *tmp_scb;
302
303   last_serial_opened = NULL;
304
305   if (serial_logfp)
306     {
307       fputs_unfiltered ("\nEnd of log\n", serial_logfp);
308       serial_current_type = 0;
309
310       /* XXX - What if serial_logfp == gdb_stdout or gdb_stderr? */
311       ui_file_delete (serial_logfp);
312       serial_logfp = NULL;
313     }
314
315 /* This is bogus.  It's not our fault if you pass us a bad scb...!  Rob, you
316    should fix your code instead.  */
317
318   if (!scb)
319     return;
320
321   scb->refcnt--;
322   if (scb->refcnt > 0)
323     return;
324
325   /* ensure that the FD has been taken out of async mode */
326   if (scb->async_handler != NULL)
327     serial_async (scb, NULL, NULL);
328
329   if (really_close)
330     scb->ops->close (scb);
331
332   if (scb->name)
333     xfree (scb->name);
334
335   if (scb_base == scb)
336     scb_base = scb_base->next;
337   else
338     for (tmp_scb = scb_base; tmp_scb; tmp_scb = tmp_scb->next)
339       {
340         if (tmp_scb->next != scb)
341           continue;
342
343         tmp_scb->next = tmp_scb->next->next;
344         break;
345       }
346
347   xfree (scb);
348 }
349
350 void
351 serial_close (struct serial *scb)
352 {
353   do_serial_close (scb, 1);
354 }
355
356 void
357 serial_un_fdopen (struct serial *scb)
358 {
359   do_serial_close (scb, 0);
360 }
361
362 int
363 serial_readchar (struct serial *scb, int timeout)
364 {
365   int ch;
366
367   /* FIXME: cagney/1999-10-11: Don't enable this check until the ASYNC
368      code is finished. */
369   if (0 && serial_is_async_p (scb) && timeout < 0)
370     internal_error (__FILE__, __LINE__,
371                     _("serial_readchar: blocking read in async mode"));
372
373   ch = scb->ops->readchar (scb, timeout);
374   if (serial_logfp != NULL)
375     {
376       serial_logchar (serial_logfp, 'r', ch, timeout);
377
378       /* Make sure that the log file is as up-to-date as possible,
379          in case we are getting ready to dump core or something. */
380       gdb_flush (serial_logfp);
381     }
382   if (serial_debug_p (scb))
383     {
384       fprintf_unfiltered (gdb_stdlog, "[");
385       serial_logchar (gdb_stdlog, 'r', ch, timeout);
386       fprintf_unfiltered (gdb_stdlog, "]");
387       gdb_flush (gdb_stdlog);
388     }
389
390   return (ch);
391 }
392
393 int
394 serial_write (struct serial *scb, const char *str, int len)
395 {
396   if (serial_logfp != NULL)
397     {
398       int count;
399
400       for (count = 0; count < len; count++)
401         serial_logchar (serial_logfp, 'w', str[count] & 0xff, 0);
402
403       /* Make sure that the log file is as up-to-date as possible,
404          in case we are getting ready to dump core or something. */
405       gdb_flush (serial_logfp);
406     }
407
408   return (scb->ops->write (scb, str, len));
409 }
410
411 void
412 serial_printf (struct serial *desc, const char *format,...)
413 {
414   va_list args;
415   char *buf;
416   va_start (args, format);
417
418   buf = xstrvprintf (format, args);
419   serial_write (desc, buf, strlen (buf));
420
421   xfree (buf);
422   va_end (args);
423 }
424
425 int
426 serial_drain_output (struct serial *scb)
427 {
428   return scb->ops->drain_output (scb);
429 }
430
431 int
432 serial_flush_output (struct serial *scb)
433 {
434   return scb->ops->flush_output (scb);
435 }
436
437 int
438 serial_flush_input (struct serial *scb)
439 {
440   return scb->ops->flush_input (scb);
441 }
442
443 int
444 serial_send_break (struct serial *scb)
445 {
446   if (serial_logfp != NULL)
447     serial_logchar (serial_logfp, 'w', SERIAL_BREAK, 0);
448
449   return (scb->ops->send_break (scb));
450 }
451
452 void
453 serial_raw (struct serial *scb)
454 {
455   scb->ops->go_raw (scb);
456 }
457
458 serial_ttystate
459 serial_get_tty_state (struct serial *scb)
460 {
461   return scb->ops->get_tty_state (scb);
462 }
463
464 int
465 serial_set_tty_state (struct serial *scb, serial_ttystate ttystate)
466 {
467   return scb->ops->set_tty_state (scb, ttystate);
468 }
469
470 void
471 serial_print_tty_state (struct serial *scb,
472                         serial_ttystate ttystate,
473                         struct ui_file *stream)
474 {
475   scb->ops->print_tty_state (scb, ttystate, stream);
476 }
477
478 int
479 serial_noflush_set_tty_state (struct serial *scb,
480                               serial_ttystate new_ttystate,
481                               serial_ttystate old_ttystate)
482 {
483   return scb->ops->noflush_set_tty_state (scb, new_ttystate, old_ttystate);
484 }
485
486 int
487 serial_setbaudrate (struct serial *scb, int rate)
488 {
489   return scb->ops->setbaudrate (scb, rate);
490 }
491
492 int
493 serial_setstopbits (struct serial *scb, int num)
494 {
495   return scb->ops->setstopbits (scb, num);
496 }
497
498 int
499 serial_can_async_p (struct serial *scb)
500 {
501   return (scb->ops->async != NULL);
502 }
503
504 int
505 serial_is_async_p (struct serial *scb)
506 {
507   return (scb->ops->async != NULL) && (scb->async_handler != NULL);
508 }
509
510 void
511 serial_async (struct serial *scb,
512               serial_event_ftype *handler,
513               void *context)
514 {
515   /* Only change mode if there is a need. */
516   if ((scb->async_handler == NULL)
517       != (handler == NULL))
518     scb->ops->async (scb, handler != NULL);
519   scb->async_handler = handler;
520   scb->async_context = context;
521 }
522
523 int
524 deprecated_serial_fd (struct serial *scb)
525 {
526   /* FIXME: should this output a warning that deprecated code is being
527      called? */
528   if (scb->fd < 0)
529     {
530       internal_error (__FILE__, __LINE__,
531                       _("serial: FD not valid"));
532     }
533   return scb->fd; /* sigh */
534 }
535
536 void
537 serial_debug (struct serial *scb, int debug_p)
538 {
539   scb->debug_p = debug_p;
540 }
541
542 int
543 serial_debug_p (struct serial *scb)
544 {
545   return scb->debug_p || global_serial_debug_p;
546 }
547
548 #ifdef USE_WIN32API
549 void
550 serial_wait_handle (struct serial *scb, HANDLE *read, HANDLE *except)
551 {
552   if (scb->ops->wait_handle)
553     scb->ops->wait_handle (scb, read, except);
554   else
555     {
556       *read = (HANDLE) _get_osfhandle (scb->fd);
557       *except = NULL;
558     }
559 }
560 #endif
561
562 #if 0
563 /* The connect command is #if 0 because I hadn't thought of an elegant
564    way to wait for I/O on two `struct serial *'s simultaneously.  Two
565    solutions came to mind:
566
567    1) Fork, and have have one fork handle the to user direction,
568    and have the other hand the to target direction.  This
569    obviously won't cut it for MSDOS.
570
571    2) Use something like select.  This assumes that stdin and
572    the target side can both be waited on via the same
573    mechanism.  This may not be true for DOS, if GDB is
574    talking to the target via a TCP socket.
575    -grossman, 8 Jun 93 */
576
577 /* Connect the user directly to the remote system.  This command acts just like
578    the 'cu' or 'tip' command.  Use <CR>~. or <CR>~^D to break out.  */
579
580 static struct serial *tty_desc; /* Controlling terminal */
581
582 static void
583 cleanup_tty (serial_ttystate ttystate)
584 {
585   printf_unfiltered ("\r\n[Exiting connect mode]\r\n");
586   serial_set_tty_state (tty_desc, ttystate);
587   xfree (ttystate);
588   serial_close (tty_desc);
589 }
590
591 static void
592 connect_command (char *args, int fromtty)
593 {
594   int c;
595   char cur_esc = 0;
596   serial_ttystate ttystate;
597   struct serial *port_desc;             /* TTY port */
598
599   dont_repeat ();
600
601   if (args)
602     fprintf_unfiltered (gdb_stderr, "This command takes no args.  They have been ignored.\n");
603
604   printf_unfiltered ("[Entering connect mode.  Use ~. or ~^D to escape]\n");
605
606   tty_desc = serial_fdopen (0);
607   port_desc = last_serial_opened;
608
609   ttystate = serial_get_tty_state (tty_desc);
610
611   serial_raw (tty_desc);
612   serial_raw (port_desc);
613
614   make_cleanup (cleanup_tty, ttystate);
615
616   while (1)
617     {
618       int mask;
619
620       mask = serial_wait_2 (tty_desc, port_desc, -1);
621
622       if (mask & 2)
623         {                       /* tty input */
624           char cx;
625
626           while (1)
627             {
628               c = serial_readchar (tty_desc, 0);
629
630               if (c == SERIAL_TIMEOUT)
631                 break;
632
633               if (c < 0)
634                 perror_with_name (_("connect"));
635
636               cx = c;
637               serial_write (port_desc, &cx, 1);
638
639               switch (cur_esc)
640                 {
641                 case 0:
642                   if (c == '\r')
643                     cur_esc = c;
644                   break;
645                 case '\r':
646                   if (c == '~')
647                     cur_esc = c;
648                   else
649                     cur_esc = 0;
650                   break;
651                 case '~':
652                   if (c == '.' || c == '\004')
653                     return;
654                   else
655                     cur_esc = 0;
656                 }
657             }
658         }
659
660       if (mask & 1)
661         {                       /* Port input */
662           char cx;
663
664           while (1)
665             {
666               c = serial_readchar (port_desc, 0);
667
668               if (c == SERIAL_TIMEOUT)
669                 break;
670
671               if (c < 0)
672                 perror_with_name (_("connect"));
673
674               cx = c;
675
676               serial_write (tty_desc, &cx, 1);
677             }
678         }
679     }
680 }
681 #endif /* 0 */
682
683 /* Serial set/show framework.  */
684
685 static struct cmd_list_element *serial_set_cmdlist;
686 static struct cmd_list_element *serial_show_cmdlist;
687
688 static void
689 serial_set_cmd (char *args, int from_tty)
690 {
691   printf_unfiltered ("\"set serial\" must be followed by the name of a command.\n");
692   help_list (serial_set_cmdlist, "set serial ", -1, gdb_stdout);
693 }
694
695 static void
696 serial_show_cmd (char *args, int from_tty)
697 {
698   cmd_show_list (serial_show_cmdlist, from_tty, "");
699 }
700
701
702 void
703 _initialize_serial (void)
704 {
705 #if 0
706   add_com ("connect", class_obscure, connect_command, _("\
707 Connect the terminal directly up to the command monitor.\n\
708 Use <CR>~. or <CR>~^D to break out."));
709 #endif /* 0 */
710
711   add_prefix_cmd ("serial", class_maintenance, serial_set_cmd, _("\
712 Set default serial/parallel port configuration."),
713                   &serial_set_cmdlist, "set serial ",
714                   0/*allow-unknown*/,
715                   &setlist);
716
717   add_prefix_cmd ("serial", class_maintenance, serial_show_cmd, _("\
718 Show default serial/parallel port configuration."),
719                   &serial_show_cmdlist, "show serial ",
720                   0/*allow-unknown*/,
721                   &showlist);
722
723   add_setshow_filename_cmd ("remotelogfile", no_class, &serial_logfile, _("\
724 Set filename for remote session recording."), _("\
725 Show filename for remote session recording."), _("\
726 This file is used to record the remote session for future playback\n\
727 by gdbserver."),
728                             NULL,
729                             NULL, /* FIXME: i18n: */
730                             &setlist, &showlist);
731
732   add_setshow_enum_cmd ("remotelogbase", no_class, logbase_enums,
733                         &serial_logbase, _("\
734 Set numerical base for remote session logging"), _("\
735 Show numerical base for remote session logging"), NULL,
736                         NULL,
737                         NULL, /* FIXME: i18n: */
738                         &setlist, &showlist);
739
740   add_setshow_zinteger_cmd ("serial", class_maintenance,
741                             &global_serial_debug_p, _("\
742 Set serial debugging."), _("\
743 Show serial debugging."), _("\
744 When non-zero, serial port debugging is enabled."),
745                             NULL,
746                             NULL, /* FIXME: i18n: */
747                             &setdebuglist, &showdebuglist);
748 }