2005-02-11 Andrew Cagney <cagney@gnu.org>
[deliverable/binutils-gdb.git] / gdb / serial.c
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 \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 (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 *
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
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
330 serial_close (struct serial *scb)
331 {
332 do_serial_close (scb, 1);
333 }
334
335 void
336 serial_un_fdopen (struct serial *scb)
337 {
338 do_serial_close (scb, 0);
339 }
340
341 int
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
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
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
405 serial_drain_output (struct serial *scb)
406 {
407 return scb->ops->drain_output (scb);
408 }
409
410 int
411 serial_flush_output (struct serial *scb)
412 {
413 return scb->ops->flush_output (scb);
414 }
415
416 int
417 serial_flush_input (struct serial *scb)
418 {
419 return scb->ops->flush_input (scb);
420 }
421
422 int
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
432 serial_raw (struct serial *scb)
433 {
434 scb->ops->go_raw (scb);
435 }
436
437 serial_ttystate
438 serial_get_tty_state (struct serial *scb)
439 {
440 return scb->ops->get_tty_state (scb);
441 }
442
443 int
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
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
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
466 serial_setbaudrate (struct serial *scb, int rate)
467 {
468 return scb->ops->setbaudrate (scb, rate);
469 }
470
471 int
472 serial_setstopbits (struct serial *scb, int num)
473 {
474 return scb->ops->setstopbits (scb, num);
475 }
476
477 int
478 serial_can_async_p (struct serial *scb)
479 {
480 return (scb->ops->async != NULL);
481 }
482
483 int
484 serial_is_async_p (struct serial *scb)
485 {
486 return (scb->ops->async != NULL) && (scb->async_handler != NULL);
487 }
488
489 void
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
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
516 serial_debug (struct serial *scb, int debug_p)
517 {
518 scb->debug_p = debug_p;
519 }
520
521 int
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
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
662 serial_show_cmd (char *args, int from_tty)
663 {
664 cmd_show_list (serial_show_cmdlist, from_tty, "");
665 }
666
667
668 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 }
This page took 0.04472 seconds and 5 git commands to generate.