2005-02-18 H.J. Lu <hongjiu.lu@intel.com>
[deliverable/binutils-gdb.git] / gdb / serial.c
CommitLineData
c906108c 1/* Generic serial interface routines
4fcf66da 2
349c5d5f
AC
3 Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
4 2001, 2002 Free Software Foundation, Inc.
c906108c 5
c5aa993b 6 This file is part of GDB.
c906108c 7
c5aa993b
JM
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.
c906108c 12
c5aa993b
JM
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.
c906108c 17
c5aa993b
JM
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. */
c906108c
SS
22
23#include "defs.h"
24#include <ctype.h>
25#include "serial.h"
26#include "gdb_string.h"
27#include "gdbcmd.h"
28
c2c6d25f 29extern void _initialize_serial (void);
392a587b 30
2acceee2
JM
31/* Is serial being debugged? */
32
33static int global_serial_debug_p;
34
c906108c
SS
35/* Linked list of serial I/O handlers */
36
37static struct serial_ops *serial_ops_list = NULL;
38
39/* This is the last serial stream opened. Used by connect command. */
40
819cc324 41static struct serial *last_serial_opened = NULL;
c906108c
SS
42
43/* Pointer to list of scb's. */
44
819cc324 45static struct serial *scb_base;
c906108c
SS
46
47/* Non-NULL gives filename which contains a recording of the remote session,
48 suitable for playback by gdbserver. */
49
50static char *serial_logfile = NULL;
d9fcf2fb 51static struct ui_file *serial_logfp = NULL;
c906108c 52
c2c6d25f 53static struct serial_ops *serial_interface_lookup (char *);
d9fcf2fb 54static void serial_logchar (struct ui_file *stream, int ch_type, int ch, int timeout);
53904c9e
AC
55static const char logbase_hex[] = "hex";
56static const char logbase_octal[] = "octal";
57static const char logbase_ascii[] = "ascii";
58static const char *logbase_enums[] =
c5aa993b 59{logbase_hex, logbase_octal, logbase_ascii, NULL};
53904c9e 60static const char *serial_logbase = logbase_ascii;
c906108c 61\f
c5aa993b 62
c906108c
SS
63static 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
71static void
d9fcf2fb 72serial_logchar (struct ui_file *stream, int ch_type, int ch, int timeout)
c906108c
SS
73{
74 if (ch_type != serial_current_type)
75 {
2acceee2 76 fprintf_unfiltered (stream, "\n%c ", ch_type);
c906108c
SS
77 serial_current_type = ch_type;
78 }
79
80 if (serial_logbase != logbase_ascii)
2acceee2 81 fputc_unfiltered (' ', stream);
c906108c
SS
82
83 switch (ch)
84 {
85 case SERIAL_TIMEOUT:
2acceee2 86 fprintf_unfiltered (stream, "<Timeout: %d seconds>", timeout);
c906108c
SS
87 return;
88 case SERIAL_ERROR:
2acceee2 89 fprintf_unfiltered (stream, "<Error: %s>", safe_strerror (errno));
c906108c
SS
90 return;
91 case SERIAL_EOF:
2acceee2 92 fputs_unfiltered ("<Eof>", stream);
c906108c
SS
93 return;
94 case SERIAL_BREAK:
2acceee2 95 fputs_unfiltered ("<Break>", stream);
c906108c
SS
96 return;
97 default:
98 if (serial_logbase == logbase_hex)
2acceee2 99 fprintf_unfiltered (stream, "%02x", ch & 0xff);
c906108c 100 else if (serial_logbase == logbase_octal)
2acceee2 101 fprintf_unfiltered (stream, "%03o", ch & 0xff);
c906108c
SS
102 else
103 switch (ch)
104 {
c5aa993b 105 case '\\':
2acceee2 106 fputs_unfiltered ("\\\\", stream);
c5aa993b
JM
107 break;
108 case '\b':
2acceee2 109 fputs_unfiltered ("\\b", stream);
c5aa993b
JM
110 break;
111 case '\f':
2acceee2 112 fputs_unfiltered ("\\f", stream);
c5aa993b
JM
113 break;
114 case '\n':
2acceee2 115 fputs_unfiltered ("\\n", stream);
c5aa993b
JM
116 break;
117 case '\r':
2acceee2 118 fputs_unfiltered ("\\r", stream);
c5aa993b
JM
119 break;
120 case '\t':
2acceee2 121 fputs_unfiltered ("\\t", stream);
c5aa993b
JM
122 break;
123 case '\v':
2acceee2 124 fputs_unfiltered ("\\v", stream);
c5aa993b
JM
125 break;
126 default:
2acceee2 127 fprintf_unfiltered (stream, isprint (ch) ? "%c" : "\\x%02x", ch & 0xFF);
c5aa993b 128 break;
c906108c
SS
129 }
130 }
131}
132
133void
c2c6d25f 134serial_log_command (const char *cmd)
c906108c
SS
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
c2c6d25f 149\f
c906108c 150static struct serial_ops *
c2c6d25f 151serial_interface_lookup (char *name)
c906108c
SS
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
162void
c2c6d25f 163serial_add_interface (struct serial_ops *optable)
c906108c
SS
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
819cc324 171struct serial *
c2c6d25f 172serial_open (const char *name)
c906108c 173{
819cc324 174 struct serial *scb;
c906108c 175 struct serial_ops *ops;
c2c6d25f 176 const char *open_name = name;
c906108c
SS
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
50a9e2f1 185 if (strcmp (name, "pc") == 0)
c906108c
SS
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");
43e526b9 191 else if (strncmp (name, "|", 1) == 0)
c2c6d25f
JM
192 {
193 ops = serial_interface_lookup ("pipe");
194 open_name = name + 1; /* discard ``|'' */
195 }
c906108c
SS
196 else
197 ops = serial_interface_lookup ("hardwire");
198
199 if (!ops)
200 return NULL;
201
65e2f740 202 scb = XMALLOC (struct serial);
c906108c
SS
203
204 scb->ops = ops;
205
206 scb->bufcnt = 0;
207 scb->bufp = scb->buf;
208
c2c6d25f 209 if (scb->ops->open (scb, open_name))
c906108c 210 {
b8c9b27d 211 xfree (scb);
c906108c
SS
212 return NULL;
213 }
214
4fcf66da 215 scb->name = xstrdup (name);
c906108c
SS
216 scb->next = scb_base;
217 scb->refcnt = 1;
2acceee2
JM
218 scb->debug_p = 0;
219 scb->async_state = 0;
c2c6d25f
JM
220 scb->async_handler = NULL;
221 scb->async_context = NULL;
c906108c
SS
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
819cc324 236struct serial *
c2c6d25f 237serial_fdopen (const int fd)
c906108c 238{
819cc324 239 struct serial *scb;
c906108c
SS
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
65e2f740 254 scb = XMALLOC (struct serial);
c906108c
SS
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;
2acceee2
JM
266 scb->debug_p = 0;
267 scb->async_state = 0;
c2c6d25f
JM
268 scb->async_handler = NULL;
269 scb->async_context = NULL;
c906108c
SS
270 scb_base = scb;
271
272 last_serial_opened = scb;
273
274 return scb;
275}
276
c2c6d25f 277static void
819cc324 278do_serial_close (struct serial *scb, int really_close)
c906108c 279{
819cc324 280 struct serial *tmp_scb;
c906108c
SS
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? */
d9fcf2fb 290 ui_file_delete (serial_logfp);
c906108c
SS
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
c2c6d25f
JM
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
c906108c
SS
308 if (really_close)
309 scb->ops->close (scb);
310
311 if (scb->name)
b8c9b27d 312 xfree (scb->name);
c906108c
SS
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
b8c9b27d 326 xfree (scb);
c906108c
SS
327}
328
c2c6d25f 329void
819cc324 330serial_close (struct serial *scb)
c2c6d25f
JM
331{
332 do_serial_close (scb, 1);
333}
334
335void
819cc324 336serial_un_fdopen (struct serial *scb)
c2c6d25f
JM
337{
338 do_serial_close (scb, 0);
339}
340
341int
819cc324 342serial_readchar (struct serial *scb, int timeout)
c2c6d25f
JM
343{
344 int ch;
345
2df3850c
JM
346 /* FIXME: cagney/1999-10-11: Don't enable this check until the ASYNC
347 code is finished. */
2cd58942 348 if (0 && serial_is_async_p (scb) && timeout < 0)
8e65ff28 349 internal_error (__FILE__, __LINE__,
e2e0b3e5 350 _("serial_readchar: blocking read in async mode"));
2df3850c 351
c2c6d25f
JM
352 ch = scb->ops->readchar (scb, timeout);
353 if (serial_logfp != NULL)
354 {
2acceee2 355 serial_logchar (serial_logfp, 'r', ch, timeout);
c2c6d25f
JM
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 }
2cd58942 361 if (serial_debug_p (scb))
2acceee2
JM
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 }
c2c6d25f
JM
368
369 return (ch);
370}
371
372int
819cc324 373serial_write (struct serial *scb, const char *str, int len)
c2c6d25f
JM
374{
375 if (serial_logfp != NULL)
376 {
377 int count;
378
379 for (count = 0; count < len; count++)
2acceee2 380 serial_logchar (serial_logfp, 'w', str[count] & 0xff, 0);
c2c6d25f
JM
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
390void
819cc324 391serial_printf (struct serial *desc, const char *format,...)
c2c6d25f
JM
392{
393 va_list args;
394 char *buf;
395 va_start (args, format);
396
e623b504 397 buf = xstrvprintf (format, args);
2cd58942 398 serial_write (desc, buf, strlen (buf));
c2c6d25f 399
b8c9b27d 400 xfree (buf);
c2c6d25f
JM
401 va_end (args);
402}
403
404int
819cc324 405serial_drain_output (struct serial *scb)
c2c6d25f
JM
406{
407 return scb->ops->drain_output (scb);
408}
409
410int
819cc324 411serial_flush_output (struct serial *scb)
c2c6d25f
JM
412{
413 return scb->ops->flush_output (scb);
414}
415
416int
819cc324 417serial_flush_input (struct serial *scb)
c2c6d25f
JM
418{
419 return scb->ops->flush_input (scb);
420}
421
422int
819cc324 423serial_send_break (struct serial *scb)
c2c6d25f
JM
424{
425 if (serial_logfp != NULL)
2acceee2 426 serial_logchar (serial_logfp, 'w', SERIAL_BREAK, 0);
c2c6d25f
JM
427
428 return (scb->ops->send_break (scb));
429}
430
431void
819cc324 432serial_raw (struct serial *scb)
c2c6d25f
JM
433{
434 scb->ops->go_raw (scb);
435}
436
437serial_ttystate
819cc324 438serial_get_tty_state (struct serial *scb)
c2c6d25f
JM
439{
440 return scb->ops->get_tty_state (scb);
441}
442
443int
819cc324 444serial_set_tty_state (struct serial *scb, serial_ttystate ttystate)
c2c6d25f
JM
445{
446 return scb->ops->set_tty_state (scb, ttystate);
447}
448
449void
819cc324 450serial_print_tty_state (struct serial *scb,
c2c6d25f 451 serial_ttystate ttystate,
d9fcf2fb 452 struct ui_file *stream)
c2c6d25f
JM
453{
454 scb->ops->print_tty_state (scb, ttystate, stream);
455}
456
457int
819cc324 458serial_noflush_set_tty_state (struct serial *scb,
c2c6d25f
JM
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
465int
819cc324 466serial_setbaudrate (struct serial *scb, int rate)
c2c6d25f
JM
467{
468 return scb->ops->setbaudrate (scb, rate);
469}
470
471int
819cc324 472serial_setstopbits (struct serial *scb, int num)
c2c6d25f
JM
473{
474 return scb->ops->setstopbits (scb, num);
475}
476
477int
819cc324 478serial_can_async_p (struct serial *scb)
c2c6d25f
JM
479{
480 return (scb->ops->async != NULL);
481}
482
483int
819cc324 484serial_is_async_p (struct serial *scb)
c2c6d25f
JM
485{
486 return (scb->ops->async != NULL) && (scb->async_handler != NULL);
487}
488
489void
819cc324 490serial_async (struct serial *scb,
c2c6d25f
JM
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
502int
819cc324 503deprecated_serial_fd (struct serial *scb)
c2c6d25f
JM
504{
505 /* FIXME: should this output a warning that deprecated code is being
506 called? */
507 if (scb->fd < 0)
508 {
8e65ff28 509 internal_error (__FILE__, __LINE__,
e2e0b3e5 510 _("serial: FD not valid"));
c2c6d25f
JM
511 }
512 return scb->fd; /* sigh */
513}
514
2acceee2 515void
819cc324 516serial_debug (struct serial *scb, int debug_p)
2acceee2
JM
517{
518 scb->debug_p = debug_p;
519}
520
521int
819cc324 522serial_debug_p (struct serial *scb)
2acceee2
JM
523{
524 return scb->debug_p || global_serial_debug_p;
525}
526
527
c906108c 528#if 0
819cc324
AC
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:
c906108c 532
c5aa993b
JM
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.
c906108c 536
c5aa993b
JM
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.
819cc324 541 -grossman, 8 Jun 93 */
c906108c
SS
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
819cc324 546static struct serial *tty_desc; /* Controlling terminal */
c906108c
SS
547
548static void
c2c6d25f 549cleanup_tty (serial_ttystate ttystate)
c906108c
SS
550{
551 printf_unfiltered ("\r\n[Exiting connect mode]\r\n");
2cd58942 552 serial_set_tty_state (tty_desc, ttystate);
b8c9b27d 553 xfree (ttystate);
2cd58942 554 serial_close (tty_desc);
c906108c
SS
555}
556
557static void
c2c6d25f 558connect_command (char *args, int fromtty)
c906108c
SS
559{
560 int c;
561 char cur_esc = 0;
562 serial_ttystate ttystate;
819cc324 563 struct serial *port_desc; /* TTY port */
c906108c 564
c5aa993b 565 dont_repeat ();
c906108c
SS
566
567 if (args)
c5aa993b
JM
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");
c906108c 571
2cd58942 572 tty_desc = serial_fdopen (0);
c906108c
SS
573 port_desc = last_serial_opened;
574
2cd58942 575 ttystate = serial_get_tty_state (tty_desc);
c906108c 576
2cd58942
AC
577 serial_raw (tty_desc);
578 serial_raw (port_desc);
c906108c
SS
579
580 make_cleanup (cleanup_tty, ttystate);
581
582 while (1)
583 {
584 int mask;
585
2cd58942 586 mask = serial_wait_2 (tty_desc, port_desc, -1);
c906108c
SS
587
588 if (mask & 2)
589 { /* tty input */
590 char cx;
591
592 while (1)
593 {
2cd58942 594 c = serial_readchar (tty_desc, 0);
c906108c
SS
595
596 if (c == SERIAL_TIMEOUT)
c5aa993b 597 break;
c906108c
SS
598
599 if (c < 0)
e2e0b3e5 600 perror_with_name (_("connect"));
c906108c
SS
601
602 cx = c;
2cd58942 603 serial_write (port_desc, &cx, 1);
c906108c
SS
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 {
2cd58942 632 c = serial_readchar (port_desc, 0);
c906108c
SS
633
634 if (c == SERIAL_TIMEOUT)
c5aa993b 635 break;
c906108c
SS
636
637 if (c < 0)
e2e0b3e5 638 perror_with_name (_("connect"));
c906108c
SS
639
640 cx = c;
641
2cd58942 642 serial_write (tty_desc, &cx, 1);
c906108c
SS
643 }
644 }
645 }
646}
647#endif /* 0 */
648
e3abfe1d
AC
649/* Serial set/show framework. */
650
651static struct cmd_list_element *serial_set_cmdlist;
652static struct cmd_list_element *serial_show_cmdlist;
653
654static void
655serial_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
661static void
662serial_show_cmd (char *args, int from_tty)
663{
664 cmd_show_list (serial_show_cmdlist, from_tty, "");
665}
666
667
c906108c 668void
c2c6d25f 669_initialize_serial (void)
c906108c
SS
670{
671#if 0
1bedd215
AC
672 add_com ("connect", class_obscure, connect_command, _("\
673Connect the terminal directly up to the command monitor.\n\
674Use <CR>~. or <CR>~^D to break out."));
c906108c
SS
675#endif /* 0 */
676
1bedd215
AC
677 add_prefix_cmd ("serial", class_maintenance, serial_set_cmd, _("\
678Set default serial/parallel port configuration."),
e3abfe1d
AC
679 &serial_set_cmdlist, "set serial ",
680 0/*allow-unknown*/,
681 &setlist);
682
1bedd215
AC
683 add_prefix_cmd ("serial", class_maintenance, serial_show_cmd, _("\
684Show default serial/parallel port configuration."),
e3abfe1d
AC
685 &serial_show_cmdlist, "show serial ",
686 0/*allow-unknown*/,
687 &showlist);
688
f397e303
AC
689 add_setshow_filename_cmd ("remotelogfile", no_class, &serial_logfile, _("\
690Set filename for remote session recording."), _("\
691Show filename for remote session recording."), _("\
c906108c 692This file is used to record the remote session for future playback\n\
f397e303
AC
693by gdbserver."),
694 NULL,
695 NULL, /* FIXME: i18n: */
696 &setlist, &showlist);
c906108c 697
cb1a6d5f 698 deprecated_add_show_from_set
c906108c 699 (add_set_enum_cmd ("remotelogbase", no_class,
1ed2a135 700 logbase_enums, &serial_logbase,
c906108c
SS
701 "Set numerical base for remote session logging",
702 &setlist),
703 &showlist);
2acceee2 704
cb1a6d5f
AC
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\
5d161b24 711When non-zero, serial port debugging is enabled.", &setdebuglist),
cb1a6d5f 712 &showdebuglist);
c906108c 713}
This page took 0.545243 seconds and 4 git commands to generate.