* cli/cli-cmds.c (apropos_command): Changed occurance of free() to xfree().
[deliverable/binutils-gdb.git] / gdb / serial.c
1 /* Generic serial interface routines
2
3 Copyright 1992, 1993, 1996, 1997, 1999, 2000, 2001 Free Software
4 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 serial_t last_serial_opened = NULL;
42
43 /* Pointer to list of scb's. */
44
45 static serial_t 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
64 static int serial_current_type = 0;
65
66 /* Log char CH of type CHTYPE, with TIMEOUT */
67
68 /* Define bogus char to represent a BREAK. Should be careful to choose a value
69 that can't be confused with a normal char, or an error code. */
70 #define SERIAL_BREAK 1235
71
72 static void
73 serial_logchar (struct ui_file *stream, int ch_type, int ch, int timeout)
74 {
75 if (ch_type != serial_current_type)
76 {
77 fprintf_unfiltered (stream, "\n%c ", ch_type);
78 serial_current_type = ch_type;
79 }
80
81 if (serial_logbase != logbase_ascii)
82 fputc_unfiltered (' ', stream);
83
84 switch (ch)
85 {
86 case SERIAL_TIMEOUT:
87 fprintf_unfiltered (stream, "<Timeout: %d seconds>", timeout);
88 return;
89 case SERIAL_ERROR:
90 fprintf_unfiltered (stream, "<Error: %s>", safe_strerror (errno));
91 return;
92 case SERIAL_EOF:
93 fputs_unfiltered ("<Eof>", stream);
94 return;
95 case SERIAL_BREAK:
96 fputs_unfiltered ("<Break>", stream);
97 return;
98 default:
99 if (serial_logbase == logbase_hex)
100 fprintf_unfiltered (stream, "%02x", ch & 0xff);
101 else if (serial_logbase == logbase_octal)
102 fprintf_unfiltered (stream, "%03o", ch & 0xff);
103 else
104 switch (ch)
105 {
106 case '\\':
107 fputs_unfiltered ("\\\\", stream);
108 break;
109 case '\b':
110 fputs_unfiltered ("\\b", stream);
111 break;
112 case '\f':
113 fputs_unfiltered ("\\f", stream);
114 break;
115 case '\n':
116 fputs_unfiltered ("\\n", stream);
117 break;
118 case '\r':
119 fputs_unfiltered ("\\r", stream);
120 break;
121 case '\t':
122 fputs_unfiltered ("\\t", stream);
123 break;
124 case '\v':
125 fputs_unfiltered ("\\v", stream);
126 break;
127 default:
128 fprintf_unfiltered (stream, isprint (ch) ? "%c" : "\\x%02x", ch & 0xFF);
129 break;
130 }
131 }
132 }
133
134 void
135 serial_log_command (const char *cmd)
136 {
137 if (!serial_logfp)
138 return;
139
140 serial_current_type = 'c';
141
142 fputs_unfiltered ("\nc ", serial_logfp);
143 fputs_unfiltered (cmd, serial_logfp);
144
145 /* Make sure that the log file is as up-to-date as possible,
146 in case we are getting ready to dump core or something. */
147 gdb_flush (serial_logfp);
148 }
149
150 \f
151 static struct serial_ops *
152 serial_interface_lookup (char *name)
153 {
154 struct serial_ops *ops;
155
156 for (ops = serial_ops_list; ops; ops = ops->next)
157 if (strcmp (name, ops->name) == 0)
158 return ops;
159
160 return NULL;
161 }
162
163 void
164 serial_add_interface (struct serial_ops *optable)
165 {
166 optable->next = serial_ops_list;
167 serial_ops_list = optable;
168 }
169
170 /* Open up a device or a network socket, depending upon the syntax of NAME. */
171
172 serial_t
173 serial_open (const char *name)
174 {
175 serial_t scb;
176 struct serial_ops *ops;
177 const char *open_name = name;
178
179 for (scb = scb_base; scb; scb = scb->next)
180 if (scb->name && strcmp (scb->name, name) == 0)
181 {
182 scb->refcnt++;
183 return scb;
184 }
185
186 if (strcmp (name, "ocd") == 0)
187 ops = serial_interface_lookup ("ocd");
188 else if (strcmp (name, "pc") == 0)
189 ops = serial_interface_lookup ("pc");
190 else if (strchr (name, ':'))
191 ops = serial_interface_lookup ("tcp");
192 else if (strncmp (name, "lpt", 3) == 0)
193 ops = serial_interface_lookup ("parallel");
194 else if (strncmp (name, "|", 1) == 0)
195 {
196 ops = serial_interface_lookup ("pipe");
197 open_name = name + 1; /* discard ``|'' */
198 }
199 else
200 ops = serial_interface_lookup ("hardwire");
201
202 if (!ops)
203 return NULL;
204
205 scb = (serial_t) xmalloc (sizeof (struct _serial_t));
206
207 scb->ops = ops;
208
209 scb->bufcnt = 0;
210 scb->bufp = scb->buf;
211
212 if (scb->ops->open (scb, open_name))
213 {
214 xfree (scb);
215 return NULL;
216 }
217
218 scb->name = xstrdup (name);
219 scb->next = scb_base;
220 scb->refcnt = 1;
221 scb->debug_p = 0;
222 scb->async_state = 0;
223 scb->async_handler = NULL;
224 scb->async_context = NULL;
225 scb_base = scb;
226
227 last_serial_opened = scb;
228
229 if (serial_logfile != NULL)
230 {
231 serial_logfp = gdb_fopen (serial_logfile, "w");
232 if (serial_logfp == NULL)
233 perror_with_name (serial_logfile);
234 }
235
236 return scb;
237 }
238
239 serial_t
240 serial_fdopen (const int fd)
241 {
242 serial_t scb;
243 struct serial_ops *ops;
244
245 for (scb = scb_base; scb; scb = scb->next)
246 if (scb->fd == fd)
247 {
248 scb->refcnt++;
249 return scb;
250 }
251
252 ops = serial_interface_lookup ("hardwire");
253
254 if (!ops)
255 return NULL;
256
257 scb = (serial_t) xmalloc (sizeof (struct _serial_t));
258
259 scb->ops = ops;
260
261 scb->bufcnt = 0;
262 scb->bufp = scb->buf;
263
264 scb->fd = fd;
265
266 scb->name = NULL;
267 scb->next = scb_base;
268 scb->refcnt = 1;
269 scb->debug_p = 0;
270 scb->async_state = 0;
271 scb->async_handler = NULL;
272 scb->async_context = NULL;
273 scb_base = scb;
274
275 last_serial_opened = scb;
276
277 return scb;
278 }
279
280 static void
281 do_serial_close (serial_t scb, int really_close)
282 {
283 serial_t tmp_scb;
284
285 last_serial_opened = NULL;
286
287 if (serial_logfp)
288 {
289 fputs_unfiltered ("\nEnd of log\n", serial_logfp);
290 serial_current_type = 0;
291
292 /* XXX - What if serial_logfp == gdb_stdout or gdb_stderr? */
293 ui_file_delete (serial_logfp);
294 serial_logfp = NULL;
295 }
296
297 /* This is bogus. It's not our fault if you pass us a bad scb...! Rob, you
298 should fix your code instead. */
299
300 if (!scb)
301 return;
302
303 scb->refcnt--;
304 if (scb->refcnt > 0)
305 return;
306
307 /* ensure that the FD has been taken out of async mode */
308 if (scb->async_handler != NULL)
309 serial_async (scb, NULL, NULL);
310
311 if (really_close)
312 scb->ops->close (scb);
313
314 if (scb->name)
315 xfree (scb->name);
316
317 if (scb_base == scb)
318 scb_base = scb_base->next;
319 else
320 for (tmp_scb = scb_base; tmp_scb; tmp_scb = tmp_scb->next)
321 {
322 if (tmp_scb->next != scb)
323 continue;
324
325 tmp_scb->next = tmp_scb->next->next;
326 break;
327 }
328
329 xfree (scb);
330 }
331
332 void
333 serial_close (serial_t scb)
334 {
335 do_serial_close (scb, 1);
336 }
337
338 void
339 serial_un_fdopen (serial_t scb)
340 {
341 do_serial_close (scb, 0);
342 }
343
344 int
345 serial_readchar (serial_t scb, int timeout)
346 {
347 int ch;
348
349 /* FIXME: cagney/1999-10-11: Don't enable this check until the ASYNC
350 code is finished. */
351 if (0 && SERIAL_IS_ASYNC_P (scb) && timeout < 0)
352 internal_error ("serial_readchar: blocking read in async mode");
353
354 ch = scb->ops->readchar (scb, timeout);
355 if (serial_logfp != NULL)
356 {
357 serial_logchar (serial_logfp, 'r', ch, timeout);
358
359 /* Make sure that the log file is as up-to-date as possible,
360 in case we are getting ready to dump core or something. */
361 gdb_flush (serial_logfp);
362 }
363 if (SERIAL_DEBUG_P (scb))
364 {
365 fprintf_unfiltered (gdb_stdlog, "[");
366 serial_logchar (gdb_stdlog, 'r', ch, timeout);
367 fprintf_unfiltered (gdb_stdlog, "]");
368 gdb_flush (gdb_stdlog);
369 }
370
371 return (ch);
372 }
373
374 int
375 serial_write (serial_t scb, const char *str, int len)
376 {
377 if (serial_logfp != NULL)
378 {
379 int count;
380
381 for (count = 0; count < len; count++)
382 serial_logchar (serial_logfp, 'w', str[count] & 0xff, 0);
383
384 /* Make sure that the log file is as up-to-date as possible,
385 in case we are getting ready to dump core or something. */
386 gdb_flush (serial_logfp);
387 }
388
389 return (scb->ops->write (scb, str, len));
390 }
391
392 void
393 serial_printf (serial_t desc, const char *format,...)
394 {
395 va_list args;
396 char *buf;
397 va_start (args, format);
398
399 xvasprintf (&buf, format, args);
400 SERIAL_WRITE (desc, buf, strlen (buf));
401
402 xfree (buf);
403 va_end (args);
404 }
405
406 int
407 serial_drain_output (serial_t scb)
408 {
409 return scb->ops->drain_output (scb);
410 }
411
412 int
413 serial_flush_output (serial_t scb)
414 {
415 return scb->ops->flush_output (scb);
416 }
417
418 int
419 serial_flush_input (serial_t scb)
420 {
421 return scb->ops->flush_input (scb);
422 }
423
424 int
425 serial_send_break (serial_t scb)
426 {
427 if (serial_logfp != NULL)
428 serial_logchar (serial_logfp, 'w', SERIAL_BREAK, 0);
429
430 return (scb->ops->send_break (scb));
431 }
432
433 void
434 serial_raw (serial_t scb)
435 {
436 scb->ops->go_raw (scb);
437 }
438
439 serial_ttystate
440 serial_get_tty_state (serial_t scb)
441 {
442 return scb->ops->get_tty_state (scb);
443 }
444
445 int
446 serial_set_tty_state (serial_t scb, serial_ttystate ttystate)
447 {
448 return scb->ops->set_tty_state (scb, ttystate);
449 }
450
451 void
452 serial_print_tty_state (serial_t scb,
453 serial_ttystate ttystate,
454 struct ui_file *stream)
455 {
456 scb->ops->print_tty_state (scb, ttystate, stream);
457 }
458
459 int
460 serial_noflush_set_tty_state (serial_t scb,
461 serial_ttystate new_ttystate,
462 serial_ttystate old_ttystate)
463 {
464 return scb->ops->noflush_set_tty_state (scb, new_ttystate, old_ttystate);
465 }
466
467 int
468 serial_setbaudrate (serial_t scb, int rate)
469 {
470 return scb->ops->setbaudrate (scb, rate);
471 }
472
473 int
474 serial_setstopbits (serial_t scb, int num)
475 {
476 return scb->ops->setstopbits (scb, num);
477 }
478
479 int
480 serial_can_async_p (serial_t scb)
481 {
482 return (scb->ops->async != NULL);
483 }
484
485 int
486 serial_is_async_p (serial_t scb)
487 {
488 return (scb->ops->async != NULL) && (scb->async_handler != NULL);
489 }
490
491 void
492 serial_async (serial_t scb,
493 serial_event_ftype *handler,
494 void *context)
495 {
496 /* Only change mode if there is a need. */
497 if ((scb->async_handler == NULL)
498 != (handler == NULL))
499 scb->ops->async (scb, handler != NULL);
500 scb->async_handler = handler;
501 scb->async_context = context;
502 }
503
504 int
505 deprecated_serial_fd (serial_t scb)
506 {
507 /* FIXME: should this output a warning that deprecated code is being
508 called? */
509 if (scb->fd < 0)
510 {
511 internal_error ("serial: FD not valid");
512 }
513 return scb->fd; /* sigh */
514 }
515
516 void
517 serial_debug (serial_t scb, int debug_p)
518 {
519 scb->debug_p = debug_p;
520 }
521
522 int
523 serial_debug_p (serial_t scb)
524 {
525 return scb->debug_p || global_serial_debug_p;
526 }
527
528
529 #if 0
530 /*
531 The connect command is #if 0 because I hadn't thought of an elegant
532 way to wait for I/O on two serial_t's simultaneously. Two solutions
533 came to mind:
534
535 1) Fork, and have have one fork handle the to user direction,
536 and have the other hand the to target direction. This
537 obviously won't cut it for MSDOS.
538
539 2) Use something like select. This assumes that stdin and
540 the target side can both be waited on via the same
541 mechanism. This may not be true for DOS, if GDB is
542 talking to the target via a TCP socket.
543 -grossman, 8 Jun 93
544 */
545
546 /* Connect the user directly to the remote system. This command acts just like
547 the 'cu' or 'tip' command. Use <CR>~. or <CR>~^D to break out. */
548
549 static serial_t tty_desc; /* Controlling terminal */
550
551 static void
552 cleanup_tty (serial_ttystate ttystate)
553 {
554 printf_unfiltered ("\r\n[Exiting connect mode]\r\n");
555 SERIAL_SET_TTY_STATE (tty_desc, ttystate);
556 xfree (ttystate);
557 SERIAL_CLOSE (tty_desc);
558 }
559
560 static void
561 connect_command (char *args, int fromtty)
562 {
563 int c;
564 char cur_esc = 0;
565 serial_ttystate ttystate;
566 serial_t port_desc; /* TTY port */
567
568 dont_repeat ();
569
570 if (args)
571 fprintf_unfiltered (gdb_stderr, "This command takes no args. They have been ignored.\n");
572
573 printf_unfiltered ("[Entering connect mode. Use ~. or ~^D to escape]\n");
574
575 tty_desc = SERIAL_FDOPEN (0);
576 port_desc = last_serial_opened;
577
578 ttystate = SERIAL_GET_TTY_STATE (tty_desc);
579
580 SERIAL_RAW (tty_desc);
581 SERIAL_RAW (port_desc);
582
583 make_cleanup (cleanup_tty, ttystate);
584
585 while (1)
586 {
587 int mask;
588
589 mask = SERIAL_WAIT_2 (tty_desc, port_desc, -1);
590
591 if (mask & 2)
592 { /* tty input */
593 char cx;
594
595 while (1)
596 {
597 c = SERIAL_READCHAR (tty_desc, 0);
598
599 if (c == SERIAL_TIMEOUT)
600 break;
601
602 if (c < 0)
603 perror_with_name ("connect");
604
605 cx = c;
606 SERIAL_WRITE (port_desc, &cx, 1);
607
608 switch (cur_esc)
609 {
610 case 0:
611 if (c == '\r')
612 cur_esc = c;
613 break;
614 case '\r':
615 if (c == '~')
616 cur_esc = c;
617 else
618 cur_esc = 0;
619 break;
620 case '~':
621 if (c == '.' || c == '\004')
622 return;
623 else
624 cur_esc = 0;
625 }
626 }
627 }
628
629 if (mask & 1)
630 { /* Port input */
631 char cx;
632
633 while (1)
634 {
635 c = SERIAL_READCHAR (port_desc, 0);
636
637 if (c == SERIAL_TIMEOUT)
638 break;
639
640 if (c < 0)
641 perror_with_name ("connect");
642
643 cx = c;
644
645 SERIAL_WRITE (tty_desc, &cx, 1);
646 }
647 }
648 }
649 }
650 #endif /* 0 */
651
652 void
653 _initialize_serial (void)
654 {
655 #if 0
656 add_com ("connect", class_obscure, connect_command,
657 "Connect the terminal directly up to the command monitor.\n\
658 Use <CR>~. or <CR>~^D to break out.");
659 #endif /* 0 */
660
661 add_show_from_set
662 (add_set_cmd ("remotelogfile", no_class,
663 var_filename, (char *) &serial_logfile,
664 "Set filename for remote session recording.\n\
665 This file is used to record the remote session for future playback\n\
666 by gdbserver.",
667 &setlist),
668 &showlist);
669
670 add_show_from_set
671 (add_set_enum_cmd ("remotelogbase", no_class,
672 logbase_enums, &serial_logbase,
673 "Set numerical base for remote session logging",
674 &setlist),
675 &showlist);
676
677 add_show_from_set (add_set_cmd ("serial",
678 class_maintenance,
679 var_zinteger,
680 (char *)&global_serial_debug_p,
681 "Set serial debugging.\n\
682 When non-zero, serial port debugging is enabled.", &setdebuglist),
683 &showdebuglist);
684 }
This page took 0.045509 seconds and 4 git commands to generate.