Merge branch 'vendor/OPENSSH'
[dragonfly.git] / contrib / gdb-7 / 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, 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 \f
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 \f
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 }