1 /* Generic serial interface routines
2 Copyright 1992, 1993, 1996, 1997 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 extern void _initialize_serial
PARAMS ((void));
28 /* Linked list of serial I/O handlers */
30 static struct serial_ops
*serial_ops_list
= NULL
;
32 /* This is the last serial stream opened. Used by connect command. */
34 static serial_t last_serial_opened
= NULL
;
36 /* Pointer to list of scb's. */
38 static serial_t scb_base
;
40 /* Non-NULL gives filename which contains a recording of the remote session,
41 suitable for playback by gdbserver. */
43 static char *serial_logfile
= NULL
;
44 static GDB_FILE
*serial_logfp
= NULL
;
46 static struct serial_ops
*serial_interface_lookup
PARAMS ((char *));
47 static void serial_logchar
PARAMS ((int, int, int));
48 static char logbase_hex
[] = "hex";
49 static char logbase_octal
[] = "octal";
50 static char logbase_ascii
[] = "ascii";
51 static char *logbase_enums
[] = {logbase_hex
, logbase_octal
, logbase_ascii
, NULL
};
52 static char *serial_logbase
= logbase_ascii
;
55 static int serial_current_type
= 0;
57 /* Log char CH of type CHTYPE, with TIMEOUT */
59 /* Define bogus char to represent a BREAK. Should be careful to choose a value
60 that can't be confused with a normal char, or an error code. */
61 #define SERIAL_BREAK 1235
64 serial_logchar (ch_type
, ch
, timeout
)
69 if (ch_type
!= serial_current_type
)
71 fprintf_unfiltered (serial_logfp
, "\n%c ", ch_type
);
72 serial_current_type
= ch_type
;
75 if (serial_logbase
!= logbase_ascii
)
76 fputc_unfiltered (' ', serial_logfp
);
81 fprintf_unfiltered (serial_logfp
, "<Timeout: %d seconds>", timeout
);
84 fprintf_unfiltered (serial_logfp
, "<Error: %s>", safe_strerror (errno
));
87 fputs_unfiltered ("<Eof>", serial_logfp
);
90 fputs_unfiltered ("<Break>", serial_logfp
);
93 if (serial_logbase
== logbase_hex
)
94 fprintf_unfiltered (serial_logfp
, "%02x", ch
& 0xff);
95 else if (serial_logbase
== logbase_octal
)
96 fprintf_unfiltered (serial_logfp
, "%03o", ch
& 0xff);
100 case '\\': fputs_unfiltered ("\\\\", serial_logfp
); break;
101 case '\b': fputs_unfiltered ("\\b", serial_logfp
); break;
102 case '\f': fputs_unfiltered ("\\f", serial_logfp
); break;
103 case '\n': fputs_unfiltered ("\\n", serial_logfp
); break;
104 case '\r': fputs_unfiltered ("\\r", serial_logfp
); break;
105 case '\t': fputs_unfiltered ("\\t", serial_logfp
); break;
106 case '\v': fputs_unfiltered ("\\v", serial_logfp
); break;
107 default: fprintf_unfiltered (serial_logfp
, isprint (ch
) ? "%c" : "\\x%02x", ch
& 0xFF); break;
113 serial_log_command (cmd
)
119 serial_current_type
= 'c';
121 fputs_unfiltered ("\nc ", serial_logfp
);
122 fputs_unfiltered (cmd
, serial_logfp
);
124 /* Make sure that the log file is as up-to-date as possible,
125 in case we are getting ready to dump core or something. */
126 gdb_flush (serial_logfp
);
130 serial_write (scb
, str
, len
)
135 if (serial_logfp
!= NULL
)
139 for (count
= 0; count
< len
; count
++)
140 serial_logchar ('w', str
[count
] & 0xff, 0);
142 /* Make sure that the log file is as up-to-date as possible,
143 in case we are getting ready to dump core or something. */
144 gdb_flush (serial_logfp
);
147 return (scb
-> ops
-> write (scb
, str
, len
));
151 serial_readchar (scb
, timeout
)
157 ch
= scb
-> ops
-> readchar (scb
, timeout
);
158 if (serial_logfp
!= NULL
)
160 serial_logchar ('r', ch
, timeout
);
162 /* Make sure that the log file is as up-to-date as possible,
163 in case we are getting ready to dump core or something. */
164 gdb_flush (serial_logfp
);
171 serial_send_break (scb
)
174 if (serial_logfp
!= NULL
)
175 serial_logchar ('w', SERIAL_BREAK
, 0);
177 return (scb
-> ops
-> send_break (scb
));
180 static struct serial_ops
*
181 serial_interface_lookup (name
)
184 struct serial_ops
*ops
;
186 for (ops
= serial_ops_list
; ops
; ops
= ops
->next
)
187 if (strcmp (name
, ops
->name
) == 0)
194 serial_add_interface(optable
)
195 struct serial_ops
*optable
;
197 optable
->next
= serial_ops_list
;
198 serial_ops_list
= optable
;
201 /* Open up a device or a network socket, depending upon the syntax of NAME. */
208 struct serial_ops
*ops
;
210 for (scb
= scb_base
; scb
; scb
= scb
->next
)
211 if (scb
->name
&& strcmp (scb
->name
, name
) == 0)
217 if (strcmp (name
, "ocd") == 0)
218 ops
= serial_interface_lookup ("ocd");
219 else if (strcmp (name
, "pc") == 0)
220 ops
= serial_interface_lookup ("pc");
221 else if (strchr (name
, ':'))
222 ops
= serial_interface_lookup ("tcp");
223 else if (strncmp (name
, "lpt", 3) == 0)
224 ops
= serial_interface_lookup ("parallel");
226 ops
= serial_interface_lookup ("hardwire");
231 scb
= (serial_t
)xmalloc (sizeof (struct _serial_t
));
236 scb
->bufp
= scb
->buf
;
238 if (scb
->ops
->open(scb
, name
))
244 scb
->name
= strsave (name
);
245 scb
->next
= scb_base
;
249 last_serial_opened
= scb
;
251 if (serial_logfile
!= NULL
)
253 serial_logfp
= gdb_fopen (serial_logfile
, "w");
254 if (serial_logfp
== NULL
)
255 perror_with_name (serial_logfile
);
266 struct serial_ops
*ops
;
268 for (scb
= scb_base
; scb
; scb
= scb
->next
)
275 ops
= serial_interface_lookup ("hardwire");
280 scb
= (serial_t
)xmalloc (sizeof (struct _serial_t
));
285 scb
->bufp
= scb
->buf
;
290 scb
->next
= scb_base
;
294 last_serial_opened
= scb
;
300 serial_close (scb
, really_close
)
306 last_serial_opened
= NULL
;
310 fputs_unfiltered ("\nEnd of log\n", serial_logfp
);
311 serial_current_type
= 0;
313 /* XXX - What if serial_logfp == gdb_stdout or gdb_stderr? */
314 gdb_fclose (&serial_logfp
);
318 /* This is bogus. It's not our fault if you pass us a bad scb...! Rob, you
319 should fix your code instead. */
329 scb
->ops
->close (scb
);
335 scb_base
= scb_base
->next
;
337 for (tmp_scb
= scb_base
; tmp_scb
; tmp_scb
= tmp_scb
->next
)
339 if (tmp_scb
->next
!= scb
)
342 tmp_scb
->next
= tmp_scb
->next
->next
;
351 The connect command is #if 0 because I hadn't thought of an elegant
352 way to wait for I/O on two serial_t's simultaneously. Two solutions
355 1) Fork, and have have one fork handle the to user direction,
356 and have the other hand the to target direction. This
357 obviously won't cut it for MSDOS.
359 2) Use something like select. This assumes that stdin and
360 the target side can both be waited on via the same
361 mechanism. This may not be true for DOS, if GDB is
362 talking to the target via a TCP socket.
366 /* Connect the user directly to the remote system. This command acts just like
367 the 'cu' or 'tip' command. Use <CR>~. or <CR>~^D to break out. */
369 static serial_t tty_desc
; /* Controlling terminal */
372 cleanup_tty(ttystate
)
373 serial_ttystate ttystate
;
375 printf_unfiltered ("\r\n[Exiting connect mode]\r\n");
376 SERIAL_SET_TTY_STATE (tty_desc
, ttystate
);
378 SERIAL_CLOSE (tty_desc
);
382 connect_command (args
, fromtty
)
388 serial_ttystate ttystate
;
389 serial_t port_desc
; /* TTY port */
394 fprintf_unfiltered(gdb_stderr
, "This command takes no args. They have been ignored.\n");
396 printf_unfiltered("[Entering connect mode. Use ~. or ~^D to escape]\n");
398 tty_desc
= SERIAL_FDOPEN (0);
399 port_desc
= last_serial_opened
;
401 ttystate
= SERIAL_GET_TTY_STATE (tty_desc
);
403 SERIAL_RAW (tty_desc
);
404 SERIAL_RAW (port_desc
);
406 make_cleanup (cleanup_tty
, ttystate
);
412 mask
= SERIAL_WAIT_2 (tty_desc
, port_desc
, -1);
420 c
= SERIAL_READCHAR(tty_desc
, 0);
422 if (c
== SERIAL_TIMEOUT
)
426 perror_with_name("connect");
429 SERIAL_WRITE(port_desc
, &cx
, 1);
444 if (c
== '.' || c
== '\004')
458 c
= SERIAL_READCHAR(port_desc
, 0);
460 if (c
== SERIAL_TIMEOUT
)
464 perror_with_name("connect");
468 SERIAL_WRITE(tty_desc
, &cx
, 1);
477 #ifdef ANSI_PROTOTYPES
478 serial_printf (serial_t desc
, const char *format
, ...)
480 serial_printf (va_alist
)
486 #ifdef ANSI_PROTOTYPES
487 va_start (args
, format
);
493 desc
= va_arg (args
, serial_t
);
494 format
= va_arg (args
, char *);
497 vasprintf (&buf
, format
, args
);
498 SERIAL_WRITE (desc
, buf
, strlen (buf
));
505 _initialize_serial ()
508 add_com ("connect", class_obscure
, connect_command
,
509 "Connect the terminal directly up to the command monitor.\n\
510 Use <CR>~. or <CR>~^D to break out.");
514 (add_set_cmd ("remotelogfile", no_class
,
515 var_filename
, (char *) &serial_logfile
,
516 "Set filename for remote session recording.\n\
517 This file is used to record the remote session for future playback\n\
523 (add_set_enum_cmd ("remotelogbase", no_class
,
524 logbase_enums
, (char *) &serial_logbase
,
525 "Set numerical base for remote session logging",