99c5a54f8323ac0d3aa2735fb0ffd0dc2138594b
[external/binutils.git] / gdb / serial.c
1 /* Generic serial interface routines
2    Copyright 1992, 1993, 1996, 1997, 1999 Free Software Foundation, Inc.
3
4    This file is part of GDB.
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2 of the License, or
9    (at your option) any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 59 Temple Place - Suite 330,
19    Boston, MA 02111-1307, USA.  */
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 serial_t last_serial_opened = NULL;
40
41 /* Pointer to list of scb's. */
42
43 static serial_t 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 GDB_FILE *serial_logfp = NULL;
50
51 static struct serial_ops *serial_interface_lookup (char *);
52 static void serial_logchar (struct gdb_file *stream, int ch_type, int ch, int timeout);
53 static char logbase_hex[] = "hex";
54 static char logbase_octal[] = "octal";
55 static char logbase_ascii[] = "ascii";
56 static char *logbase_enums[] =
57 {logbase_hex, logbase_octal, logbase_ascii, NULL};
58 static char *serial_logbase = logbase_ascii;
59 \f
60
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 gdb_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 serial_t
171 serial_open (const char *name)
172 {
173   serial_t 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, "ocd") == 0)
185     ops = serial_interface_lookup ("ocd");
186   else if (strcmp (name, "pc") == 0)
187     ops = serial_interface_lookup ("pc");
188   else if (strchr (name, ':'))
189     ops = serial_interface_lookup ("tcp");
190   else if (strncmp (name, "lpt", 3) == 0)
191     ops = serial_interface_lookup ("parallel");
192   else if (strncmp (name, "|", 1) == 0)
193     {
194       ops = serial_interface_lookup ("pipe");
195       open_name = name + 1; /* discard ``|'' */
196     }
197   else
198     ops = serial_interface_lookup ("hardwire");
199
200   if (!ops)
201     return NULL;
202
203   scb = (serial_t) xmalloc (sizeof (struct _serial_t));
204
205   scb->ops = ops;
206
207   scb->bufcnt = 0;
208   scb->bufp = scb->buf;
209
210   if (scb->ops->open (scb, open_name))
211     {
212       free (scb);
213       return NULL;
214     }
215
216   scb->name = strsave (name);
217   scb->next = scb_base;
218   scb->refcnt = 1;
219   scb->debug_p = 0;
220   scb->async_state = 0;
221   scb->async_handler = NULL;
222   scb->async_context = NULL;
223   scb_base = scb;
224
225   last_serial_opened = scb;
226
227   if (serial_logfile != NULL)
228     {
229       serial_logfp = gdb_fopen (serial_logfile, "w");
230       if (serial_logfp == NULL)
231         perror_with_name (serial_logfile);
232     }
233
234   return scb;
235 }
236
237 serial_t
238 serial_fdopen (const int fd)
239 {
240   serial_t scb;
241   struct serial_ops *ops;
242
243   for (scb = scb_base; scb; scb = scb->next)
244     if (scb->fd == fd)
245       {
246         scb->refcnt++;
247         return scb;
248       }
249
250   ops = serial_interface_lookup ("hardwire");
251
252   if (!ops)
253     return NULL;
254
255   scb = (serial_t) xmalloc (sizeof (struct _serial_t));
256
257   scb->ops = ops;
258
259   scb->bufcnt = 0;
260   scb->bufp = scb->buf;
261
262   scb->fd = fd;
263
264   scb->name = NULL;
265   scb->next = scb_base;
266   scb->refcnt = 1;
267   scb->debug_p = 0;
268   scb->async_state = 0;
269   scb->async_handler = NULL;
270   scb->async_context = NULL;
271   scb_base = scb;
272
273   last_serial_opened = scb;
274
275   return scb;
276 }
277
278 static void
279 do_serial_close (serial_t scb, int really_close)
280 {
281   serial_t tmp_scb;
282
283   last_serial_opened = NULL;
284
285   if (serial_logfp)
286     {
287       fputs_unfiltered ("\nEnd of log\n", serial_logfp);
288       serial_current_type = 0;
289
290       /* XXX - What if serial_logfp == gdb_stdout or gdb_stderr? */
291       gdb_fclose (&serial_logfp);
292       serial_logfp = NULL;
293     }
294
295 /* This is bogus.  It's not our fault if you pass us a bad scb...!  Rob, you
296    should fix your code instead.  */
297
298   if (!scb)
299     return;
300
301   scb->refcnt--;
302   if (scb->refcnt > 0)
303     return;
304
305   /* ensure that the FD has been taken out of async mode */
306   if (scb->async_handler != NULL)
307     serial_async (scb, NULL, NULL);
308
309   if (really_close)
310     scb->ops->close (scb);
311
312   if (scb->name)
313     free (scb->name);
314
315   if (scb_base == scb)
316     scb_base = scb_base->next;
317   else
318     for (tmp_scb = scb_base; tmp_scb; tmp_scb = tmp_scb->next)
319       {
320         if (tmp_scb->next != scb)
321           continue;
322
323         tmp_scb->next = tmp_scb->next->next;
324         break;
325       }
326
327   free (scb);
328 }
329
330 void
331 serial_close (serial_t scb)
332 {
333   do_serial_close (scb, 1);
334 }
335
336 void
337 serial_un_fdopen (serial_t scb)
338 {
339   do_serial_close (scb, 0);
340 }
341
342 int
343 serial_readchar (serial_t scb, int timeout)
344 {
345   int ch;
346
347   ch = scb->ops->readchar (scb, timeout);
348   if (serial_logfp != NULL)
349     {
350       serial_logchar (serial_logfp, 'r', ch, timeout);
351
352       /* Make sure that the log file is as up-to-date as possible,
353          in case we are getting ready to dump core or something. */
354       gdb_flush (serial_logfp);
355     }
356   if (SERIAL_DEBUG_P (scb))
357     {
358       fprintf_unfiltered (gdb_stdlog, "[");
359       serial_logchar (gdb_stdlog, 'r', ch, timeout);
360       fprintf_unfiltered (gdb_stdlog, "]");
361       gdb_flush (gdb_stdlog);
362     }
363
364   return (ch);
365 }
366
367 int
368 serial_write (serial_t scb, const char *str, int len)
369 {
370   if (serial_logfp != NULL)
371     {
372       int count;
373
374       for (count = 0; count < len; count++)
375         serial_logchar (serial_logfp, 'w', str[count] & 0xff, 0);
376
377       /* Make sure that the log file is as up-to-date as possible,
378          in case we are getting ready to dump core or something. */
379       gdb_flush (serial_logfp);
380     }
381
382   return (scb->ops->write (scb, str, len));
383 }
384
385 void
386 serial_printf (serial_t desc, const char *format,...)
387 {
388   va_list args;
389   char *buf;
390   va_start (args, format);
391
392   vasprintf (&buf, format, args);
393   SERIAL_WRITE (desc, buf, strlen (buf));
394
395   free (buf);
396   va_end (args);
397 }
398
399 int
400 serial_drain_output (serial_t scb)
401 {
402   return scb->ops->drain_output (scb);
403 }
404
405 int
406 serial_flush_output (serial_t scb)
407 {
408   return scb->ops->flush_output (scb);
409 }
410
411 int
412 serial_flush_input (serial_t scb)
413 {
414   return scb->ops->flush_input (scb);
415 }
416
417 int
418 serial_send_break (serial_t scb)
419 {
420   if (serial_logfp != NULL)
421     serial_logchar (serial_logfp, 'w', SERIAL_BREAK, 0);
422
423   return (scb->ops->send_break (scb));
424 }
425
426 void
427 serial_raw (serial_t scb)
428 {
429   scb->ops->go_raw (scb);
430 }
431
432 serial_ttystate
433 serial_get_tty_state (serial_t scb)
434 {
435   return scb->ops->get_tty_state (scb);
436 }
437
438 int
439 serial_set_tty_state (serial_t scb, serial_ttystate ttystate)
440 {
441   return scb->ops->set_tty_state (scb, ttystate);
442 }
443
444 void
445 serial_print_tty_state (serial_t scb,
446                         serial_ttystate ttystate,
447                         struct gdb_file *stream)
448 {
449   scb->ops->print_tty_state (scb, ttystate, stream);
450 }
451
452 int
453 serial_noflush_set_tty_state (serial_t scb,
454                               serial_ttystate new_ttystate,
455                               serial_ttystate old_ttystate)
456 {
457   return scb->ops->noflush_set_tty_state (scb, new_ttystate, old_ttystate);
458 }
459
460 int
461 serial_setbaudrate (serial_t scb, int rate)
462 {
463   return scb->ops->setbaudrate (scb, rate);
464 }
465
466 int
467 serial_setstopbits (serial_t scb, int num)
468 {
469   return scb->ops->setstopbits (scb, num);
470 }
471
472 int
473 serial_can_async_p (serial_t scb)
474 {
475   return (scb->ops->async != NULL);
476 }
477
478 int
479 serial_is_async_p (serial_t scb)
480 {
481   return (scb->ops->async != NULL) && (scb->async_handler != NULL);
482 }
483
484 void
485 serial_async (serial_t scb,
486               serial_event_ftype *handler,
487               void *context)
488 {
489   /* Only change mode if there is a need. */
490   if ((scb->async_handler == NULL)
491       != (handler == NULL))
492     scb->ops->async (scb, handler != NULL);
493   scb->async_handler = handler;
494   scb->async_context = context;
495 }
496
497 int
498 deprecated_serial_fd (serial_t scb)
499 {
500   /* FIXME: should this output a warning that deprecated code is being
501      called? */
502   if (scb->fd < 0)
503     {
504       internal_error ("serial: FD not valid");
505     }
506   return scb->fd; /* sigh */
507 }
508
509 void
510 serial_debug (serial_t scb, int debug_p)
511 {
512   scb->debug_p = debug_p;
513 }
514
515 int
516 serial_debug_p (serial_t scb)
517 {
518   return scb->debug_p || global_serial_debug_p;
519 }
520
521
522 #if 0
523 /*
524    The connect command is #if 0 because I hadn't thought of an elegant
525    way to wait for I/O on two serial_t's simultaneously.  Two solutions
526    came to mind:
527
528    1) Fork, and have have one fork handle the to user direction,
529    and have the other hand the to target direction.  This
530    obviously won't cut it for MSDOS.
531
532    2) Use something like select.  This assumes that stdin and
533    the target side can both be waited on via the same
534    mechanism.  This may not be true for DOS, if GDB is
535    talking to the target via a TCP socket.
536    -grossman, 8 Jun 93
537  */
538
539 /* Connect the user directly to the remote system.  This command acts just like
540    the 'cu' or 'tip' command.  Use <CR>~. or <CR>~^D to break out.  */
541
542 static serial_t tty_desc;       /* Controlling terminal */
543
544 static void
545 cleanup_tty (serial_ttystate ttystate)
546 {
547   printf_unfiltered ("\r\n[Exiting connect mode]\r\n");
548   SERIAL_SET_TTY_STATE (tty_desc, ttystate);
549   free (ttystate);
550   SERIAL_CLOSE (tty_desc);
551 }
552
553 static void
554 connect_command (char *args, int fromtty)
555 {
556   int c;
557   char cur_esc = 0;
558   serial_ttystate ttystate;
559   serial_t port_desc;           /* TTY port */
560
561   dont_repeat ();
562
563   if (args)
564     fprintf_unfiltered (gdb_stderr, "This command takes no args.  They have been ignored.\n");
565
566   printf_unfiltered ("[Entering connect mode.  Use ~. or ~^D to escape]\n");
567
568   tty_desc = SERIAL_FDOPEN (0);
569   port_desc = last_serial_opened;
570
571   ttystate = SERIAL_GET_TTY_STATE (tty_desc);
572
573   SERIAL_RAW (tty_desc);
574   SERIAL_RAW (port_desc);
575
576   make_cleanup (cleanup_tty, ttystate);
577
578   while (1)
579     {
580       int mask;
581
582       mask = SERIAL_WAIT_2 (tty_desc, port_desc, -1);
583
584       if (mask & 2)
585         {                       /* tty input */
586           char cx;
587
588           while (1)
589             {
590               c = SERIAL_READCHAR (tty_desc, 0);
591
592               if (c == SERIAL_TIMEOUT)
593                 break;
594
595               if (c < 0)
596                 perror_with_name ("connect");
597
598               cx = c;
599               SERIAL_WRITE (port_desc, &cx, 1);
600
601               switch (cur_esc)
602                 {
603                 case 0:
604                   if (c == '\r')
605                     cur_esc = c;
606                   break;
607                 case '\r':
608                   if (c == '~')
609                     cur_esc = c;
610                   else
611                     cur_esc = 0;
612                   break;
613                 case '~':
614                   if (c == '.' || c == '\004')
615                     return;
616                   else
617                     cur_esc = 0;
618                 }
619             }
620         }
621
622       if (mask & 1)
623         {                       /* Port input */
624           char cx;
625
626           while (1)
627             {
628               c = SERIAL_READCHAR (port_desc, 0);
629
630               if (c == SERIAL_TIMEOUT)
631                 break;
632
633               if (c < 0)
634                 perror_with_name ("connect");
635
636               cx = c;
637
638               SERIAL_WRITE (tty_desc, &cx, 1);
639             }
640         }
641     }
642 }
643 #endif /* 0 */
644
645 void
646 _initialize_serial (void)
647 {
648 #if 0
649   add_com ("connect", class_obscure, connect_command,
650            "Connect the terminal directly up to the command monitor.\n\
651 Use <CR>~. or <CR>~^D to break out.");
652 #endif /* 0 */
653
654   add_show_from_set
655     (add_set_cmd ("remotelogfile", no_class,
656                   var_filename, (char *) &serial_logfile,
657                   "Set filename for remote session recording.\n\
658 This file is used to record the remote session for future playback\n\
659 by gdbserver.",
660                   &setlist),
661      &showlist);
662
663   add_show_from_set
664     (add_set_enum_cmd ("remotelogbase", no_class,
665                        logbase_enums, (char *) &serial_logbase,
666                        "Set numerical base for remote session logging",
667                        &setlist),
668      &showlist);
669
670   add_show_from_set (add_set_cmd ("serialdebug",
671                                   class_maintenance,
672                                   var_zinteger,
673                                   (char *)&global_serial_debug_p,
674                                   "Set serial debugging.\n\
675 When non-zero, serial port debugging is enabled.", &setlist),
676                      &showlist);
677 }