1 /* Generic serial interface routines
2 Copyright 1992, 1993, 1996 Free Software Foundation, Inc.
4 This file is part of GDB.
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.
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.
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, Boston, MA 02111-1307, USA. */
23 #include "gdb_string.h"
26 /* Linked list of serial I/O handlers */
28 static struct serial_ops *serial_ops_list = NULL;
30 /* This is the last serial stream opened. Used by connect command. */
32 static serial_t last_serial_opened = NULL;
34 /* Pointer to list of scb's. */
36 static serial_t scb_base;
38 /* Non-NULL gives filename which contains a recording of the remote session,
39 suitable for playback by gdbserver. */
41 char *serial_logfile = NULL;
42 FILE *serial_logfp = NULL;
44 static struct serial_ops *serial_interface_lookup PARAMS ((char *));
45 static void serial_logchar PARAMS ((int));
48 static int serial_reading = 0;
49 static int serial_writing = 0;
52 serial_log_command (cmd)
55 if (serial_reading || serial_writing)
57 fputc_unfiltered ('\n', serial_logfp);
61 fprintf_unfiltered (serial_logfp, "c %s\n", cmd);
62 /* Make sure that the log file is as up-to-date as possible,
63 in case we are getting ready to dump core or something. */
64 fflush (serial_logfp);
73 case '\\': fputs_unfiltered ("\\\\", serial_logfp); break;
74 case '\b': fputs_unfiltered ("\\b", serial_logfp); break;
75 case '\f': fputs_unfiltered ("\\f", serial_logfp); break;
76 case '\n': fputs_unfiltered ("\\n", serial_logfp); break;
77 case '\r': fputs_unfiltered ("\\r", serial_logfp); break;
78 case '\t': fputs_unfiltered ("\\t", serial_logfp); break;
79 case '\v': fputs_unfiltered ("\\v", serial_logfp); break;
80 default: fprintf_unfiltered (serial_logfp, isprint (ch) ? "%c" : "\\x%02x", ch & 0xFF); break;
85 serial_write (scb, str, len)
92 if (serial_logfp != NULL)
96 fputc_unfiltered ('\n', serial_logfp);
101 serial_logchar ('w');
102 serial_logchar (' ');
105 for (count = 0; count < len; count++)
107 serial_logchar (str[count]);
109 /* Make sure that the log file is as up-to-date as possible,
110 in case we are getting ready to dump core or something. */
111 fflush (serial_logfp);
113 return (scb -> ops -> write (scb, str, len));
117 serial_readchar (scb, timeout)
123 ch = scb -> ops -> readchar (scb, timeout);
124 if (serial_logfp != NULL)
128 fputc_unfiltered ('\n', serial_logfp);
133 serial_logchar ('r');
134 serial_logchar (' ');
138 /* Make sure that the log file is as up-to-date as possible,
139 in case we are getting ready to dump core or something. */
140 fflush (serial_logfp);
145 static struct serial_ops *
146 serial_interface_lookup (name)
149 struct serial_ops *ops;
151 for (ops = serial_ops_list; ops; ops = ops->next)
152 if (strcmp (name, ops->name) == 0)
159 serial_add_interface(optable)
160 struct serial_ops *optable;
162 optable->next = serial_ops_list;
163 serial_ops_list = optable;
166 /* Open up a device or a network socket, depending upon the syntax of NAME. */
173 struct serial_ops *ops;
175 for (scb = scb_base; scb; scb = scb->next)
176 if (scb->name && strcmp (scb->name, name) == 0)
182 if (strcmp (name, "pc") == 0)
183 ops = serial_interface_lookup ("pc");
184 else if (strchr (name, ':'))
185 ops = serial_interface_lookup ("tcp");
186 else if (strncmp (name, "lpt", 3) == 0)
187 ops = serial_interface_lookup ("parallel");
189 ops = serial_interface_lookup ("hardwire");
194 scb = (serial_t)xmalloc (sizeof (struct _serial_t));
199 scb->bufp = scb->buf;
201 if (scb->ops->open(scb, name))
207 scb->name = strsave (name);
208 scb->next = scb_base;
212 last_serial_opened = scb;
214 if (serial_logfile != NULL)
216 serial_logfp = fopen (serial_logfile, "w");
217 if (serial_logfp == NULL)
219 perror_with_name (serial_logfile);
231 struct serial_ops *ops;
233 for (scb = scb_base; scb; scb = scb->next)
240 ops = serial_interface_lookup ("hardwire");
245 scb = (serial_t)xmalloc (sizeof (struct _serial_t));
250 scb->bufp = scb->buf;
255 scb->next = scb_base;
259 last_serial_opened = scb;
265 serial_close(scb, really_close)
271 last_serial_opened = NULL;
275 if (serial_reading || serial_writing)
277 fputc_unfiltered ('\n', serial_logfp);
281 fclose (serial_logfp);
285 /* This is bogus. It's not our fault if you pass us a bad scb...! Rob, you
286 should fix your code instead. */
296 scb->ops->close (scb);
302 scb_base = scb_base->next;
304 for (tmp_scb = scb_base; tmp_scb; tmp_scb = tmp_scb->next)
306 if (tmp_scb->next != scb)
309 tmp_scb->next = tmp_scb->next->next;
318 The connect command is #if 0 because I hadn't thought of an elegant
319 way to wait for I/O on two serial_t's simultaneously. Two solutions
322 1) Fork, and have have one fork handle the to user direction,
323 and have the other hand the to target direction. This
324 obviously won't cut it for MSDOS.
326 2) Use something like select. This assumes that stdin and
327 the target side can both be waited on via the same
328 mechanism. This may not be true for DOS, if GDB is
329 talking to the target via a TCP socket.
333 /* Connect the user directly to the remote system. This command acts just like
334 the 'cu' or 'tip' command. Use <CR>~. or <CR>~^D to break out. */
336 static serial_t tty_desc; /* Controlling terminal */
339 cleanup_tty(ttystate)
340 serial_ttystate ttystate;
342 printf_unfiltered ("\r\n[Exiting connect mode]\r\n");
343 SERIAL_SET_TTY_STATE (tty_desc, ttystate);
345 SERIAL_CLOSE (tty_desc);
349 connect_command (args, fromtty)
355 serial_ttystate ttystate;
356 serial_t port_desc; /* TTY port */
361 fprintf_unfiltered(gdb_stderr, "This command takes no args. They have been ignored.\n");
363 printf_unfiltered("[Entering connect mode. Use ~. or ~^D to escape]\n");
365 tty_desc = SERIAL_FDOPEN (0);
366 port_desc = last_serial_opened;
368 ttystate = SERIAL_GET_TTY_STATE (tty_desc);
370 SERIAL_RAW (tty_desc);
371 SERIAL_RAW (port_desc);
373 make_cleanup (cleanup_tty, ttystate);
379 mask = SERIAL_WAIT_2 (tty_desc, port_desc, -1);
387 c = SERIAL_READCHAR(tty_desc, 0);
389 if (c == SERIAL_TIMEOUT)
393 perror_with_name("connect");
396 SERIAL_WRITE(port_desc, &cx, 1);
411 if (c == '.' || c == '\004')
425 c = SERIAL_READCHAR(port_desc, 0);
427 if (c == SERIAL_TIMEOUT)
431 perror_with_name("connect");
435 SERIAL_WRITE(tty_desc, &cx, 1);
444 #ifdef ANSI_PROTOTYPES
445 serial_printf (serial_t desc, const char *format, ...)
447 serial_printf (va_alist)
453 #ifdef ANSI_PROTOTYPES
454 va_start (args, format);
460 desc = va_arg (args, serial_t);
461 format = va_arg (args, char *);
464 vasprintf (&buf, format, args);
465 SERIAL_WRITE (desc, buf, strlen (buf));
472 _initialize_serial ()
475 add_com ("connect", class_obscure, connect_command,
476 "Connect the terminal directly up to the command monitor.\n\
477 Use <CR>~. or <CR>~^D to break out.");
480 add_show_from_set (add_set_cmd ("remotelogfile", no_class,
481 var_filename, (char *)&serial_logfile,
482 "Set filename for remote session recording.\n\
483 This file is used to record the remote session for future playback\n\
484 by gdbserver.", &setlist),