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