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