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"
30 /* Linked list of serial I/O handlers */
32 static struct serial_ops
*serial_ops_list
= NULL
;
34 /* This is the last serial stream opened. Used by connect command. */
36 static serial_t last_serial_opened
= NULL
;
38 /* Pointer to list of scb's. */
40 static serial_t scb_base
;
42 /* Non-NULL gives filename which contains a recording of the remote session,
43 suitable for playback by gdbserver. */
45 static char *serial_logfile
= NULL
;
46 static FILE *serial_logfp
= NULL
;
48 static struct serial_ops
*serial_interface_lookup
PARAMS ((char *));
49 static void serial_logchar
PARAMS ((int ch
, int timeout
));
50 static char logbase_hex
[] = "hex";
51 static char logbase_octal
[] = "octal";
52 static char logbase_ascii
[] = "ascii";
53 static char *logbase_enums
[] = {logbase_hex
, logbase_octal
, logbase_ascii
, NULL
};
54 static char *serial_logbase
= logbase_ascii
;
57 static int serial_reading
= 0;
58 static int serial_writing
= 0;
61 serial_log_command (cmd
)
67 if (serial_reading
|| serial_writing
)
69 fputc_unfiltered ('\n', serial_logfp
);
73 fprintf_unfiltered (serial_logfp
, "c %s\n", cmd
);
74 /* Make sure that the log file is as up-to-date as possible,
75 in case we are getting ready to dump core or something. */
76 fflush (serial_logfp
);
79 /* Define bogus char to represent a BREAK. Should be careful to choose a value
80 that can't be confused with a normal char, or an error code. */
81 #define SERIAL_BREAK 1235
84 serial_logchar (ch
, timeout
)
88 if (serial_logbase
!= logbase_ascii
)
89 fputc_unfiltered (' ', serial_logfp
);
94 fprintf_unfiltered (serial_logfp
, "<Timeout: %d seconds>", timeout
);
97 fprintf_unfiltered (serial_logfp
, "<Error: %s>", safe_strerror (errno
));
100 fputs_unfiltered ("<Eof>", serial_logfp
);
103 fputs_unfiltered ("<Break>", serial_logfp
);
106 if (serial_logbase
== logbase_hex
)
107 fprintf_unfiltered (serial_logfp
, "%02x", ch
& 0xff);
108 else if (serial_logbase
== logbase_octal
)
109 fprintf_unfiltered (serial_logfp
, "%03o", ch
& 0xff);
113 case '\\': fputs_unfiltered ("\\\\", serial_logfp
); break;
114 case '\b': fputs_unfiltered ("\\b", serial_logfp
); break;
115 case '\f': fputs_unfiltered ("\\f", serial_logfp
); break;
116 case '\n': fputs_unfiltered ("\\n", serial_logfp
); break;
117 case '\r': fputs_unfiltered ("\\r", serial_logfp
); break;
118 case '\t': fputs_unfiltered ("\\t", serial_logfp
); break;
119 case '\v': fputs_unfiltered ("\\v", serial_logfp
); break;
120 default: fprintf_unfiltered (serial_logfp
, isprint (ch
) ? "%c" : "\\x%02x", ch
& 0xFF); break;
126 serial_write (scb
, str
, len
)
133 if (serial_logfp
!= NULL
)
137 fputc_unfiltered ('\n', serial_logfp
);
142 fputs_unfiltered ("w ", serial_logfp
);
145 for (count
= 0; count
< len
; count
++)
147 serial_logchar (str
[count
] & 0xff, 0);
149 /* Make sure that the log file is as up-to-date as possible,
150 in case we are getting ready to dump core or something. */
151 fflush (serial_logfp
);
153 return (scb
-> ops
-> write (scb
, str
, len
));
157 serial_readchar (scb
, timeout
)
163 ch
= scb
-> ops
-> readchar (scb
, timeout
);
164 if (serial_logfp
!= NULL
)
168 fputc_unfiltered ('\n', serial_logfp
);
173 fputs_unfiltered ("r ", serial_logfp
);
176 serial_logchar (ch
, timeout
);
177 /* Make sure that the log file is as up-to-date as possible,
178 in case we are getting ready to dump core or something. */
179 fflush (serial_logfp
);
185 serial_send_break (scb
)
188 if (serial_logfp
!= NULL
)
192 fputc_unfiltered ('\n', serial_logfp
);
197 fputs_unfiltered ("w ", serial_logfp
);
200 serial_logchar (SERIAL_BREAK
, 0);
201 /* Make sure that the log file is as up-to-date as possible,
202 in case we are getting ready to dump core or something. */
203 fflush (serial_logfp
);
205 return (scb
-> ops
-> send_break (scb
));
208 static struct serial_ops
*
209 serial_interface_lookup (name
)
212 struct serial_ops
*ops
;
213 DBG(("serial_interface_lookup(%s)\n",name
));
215 for (ops
= serial_ops_list
; ops
; ops
= ops
->next
)
216 if (strcmp (name
, ops
->name
) == 0)
219 DBG(("serial_interface_lookup: %s not found!\n",name
));
224 serial_add_interface(optable
)
225 struct serial_ops
*optable
;
227 optable
->next
= serial_ops_list
;
228 serial_ops_list
= optable
;
231 /* Open up a device or a network socket, depending upon the syntax of NAME. */
238 struct serial_ops
*ops
;
240 DBG(("serial_open\n"));
241 for (scb
= scb_base
; scb
; scb
= scb
->next
)
242 if (scb
->name
&& strcmp (scb
->name
, name
) == 0)
245 DBG(("serial_open: scb %s found\n", name
));
249 if (strcmp (name
, "pc") == 0)
250 ops
= serial_interface_lookup ("pc");
251 else if (strchr (name
, ':'))
252 ops
= serial_interface_lookup ("tcp");
253 else if (strncmp (name
, "lpt", 3) == 0)
254 ops
= serial_interface_lookup ("parallel");
256 ops
= serial_interface_lookup ("hardwire");
260 DBG(("serial_open: !ops; returning NULL\n"));
264 scb
= (serial_t
)xmalloc (sizeof (struct _serial_t
));
269 scb
->bufp
= scb
->buf
;
271 if (scb
->ops
->open(scb
, name
))
274 DBG(("serial_open: scb->ops->open failed!\n"));
278 scb
->name
= strsave (name
);
279 scb
->next
= scb_base
;
283 last_serial_opened
= scb
;
285 if (serial_logfile
!= NULL
)
287 serial_logfp
= fopen (serial_logfile
, "w");
288 if (serial_logfp
== NULL
)
290 DBG(("serial_open: unable to open serial logfile %s!\n",serial_logfile
));
291 perror_with_name (serial_logfile
);
295 DBG(("serial_open: Done! :-)\n"));
304 struct serial_ops
*ops
;
305 DBG(("serial_fdopen\n"));
307 for (scb
= scb_base
; scb
; scb
= scb
->next
)
314 ops
= serial_interface_lookup ("hardwire");
319 scb
= (serial_t
)xmalloc (sizeof (struct _serial_t
));
324 scb
->bufp
= scb
->buf
;
329 scb
->next
= scb_base
;
333 last_serial_opened
= scb
;
339 serial_close(scb
, really_close
)
345 last_serial_opened
= NULL
;
349 if (serial_reading
|| serial_writing
)
351 fputc_unfiltered ('\n', serial_logfp
);
355 fclose (serial_logfp
);
359 /* This is bogus. It's not our fault if you pass us a bad scb...! Rob, you
360 should fix your code instead. */
370 scb
->ops
->close (scb
);
376 scb_base
= scb_base
->next
;
378 for (tmp_scb
= scb_base
; tmp_scb
; tmp_scb
= tmp_scb
->next
)
380 if (tmp_scb
->next
!= scb
)
383 tmp_scb
->next
= tmp_scb
->next
->next
;
392 The connect command is #if 0 because I hadn't thought of an elegant
393 way to wait for I/O on two serial_t's simultaneously. Two solutions
396 1) Fork, and have have one fork handle the to user direction,
397 and have the other hand the to target direction. This
398 obviously won't cut it for MSDOS.
400 2) Use something like select. This assumes that stdin and
401 the target side can both be waited on via the same
402 mechanism. This may not be true for DOS, if GDB is
403 talking to the target via a TCP socket.
407 /* Connect the user directly to the remote system. This command acts just like
408 the 'cu' or 'tip' command. Use <CR>~. or <CR>~^D to break out. */
410 static serial_t tty_desc
; /* Controlling terminal */
413 cleanup_tty(ttystate
)
414 serial_ttystate ttystate
;
416 printf_unfiltered ("\r\n[Exiting connect mode]\r\n");
417 SERIAL_SET_TTY_STATE (tty_desc
, ttystate
);
419 SERIAL_CLOSE (tty_desc
);
423 connect_command (args
, fromtty
)
429 serial_ttystate ttystate
;
430 serial_t port_desc
; /* TTY port */
431 DBG(("connect_command\n"));
436 fprintf_unfiltered(gdb_stderr
, "This command takes no args. They have been ignored.\n");
438 printf_unfiltered("[Entering connect mode. Use ~. or ~^D to escape]\n");
440 tty_desc
= SERIAL_FDOPEN (0);
441 port_desc
= last_serial_opened
;
443 ttystate
= SERIAL_GET_TTY_STATE (tty_desc
);
445 SERIAL_RAW (tty_desc
);
446 SERIAL_RAW (port_desc
);
448 make_cleanup (cleanup_tty
, ttystate
);
454 mask
= SERIAL_WAIT_2 (tty_desc
, port_desc
, -1);
462 c
= SERIAL_READCHAR(tty_desc
, 0);
464 if (c
== SERIAL_TIMEOUT
)
468 perror_with_name("connect");
471 SERIAL_WRITE(port_desc
, &cx
, 1);
486 if (c
== '.' || c
== '\004')
500 c
= SERIAL_READCHAR(port_desc
, 0);
502 if (c
== SERIAL_TIMEOUT
)
506 perror_with_name("connect");
510 SERIAL_WRITE(tty_desc
, &cx
, 1);
519 #ifdef ANSI_PROTOTYPES
520 serial_printf (serial_t desc
, const char *format
, ...)
522 serial_printf (va_alist
)
528 #ifdef ANSI_PROTOTYPES
529 va_start (args
, format
);
535 desc
= va_arg (args
, serial_t
);
536 format
= va_arg (args
, char *);
539 vasprintf (&buf
, format
, args
);
540 SERIAL_WRITE (desc
, buf
, strlen (buf
));
547 _initialize_serial ()
549 struct cmd_list_element
*cmd
;
552 add_com ("connect", class_obscure
, connect_command
,
553 "Connect the terminal directly up to the command monitor.\n\
554 Use <CR>~. or <CR>~^D to break out.");
557 add_show_from_set (add_set_cmd ("remotelogfile", no_class
,
558 var_filename
, (char *)&serial_logfile
,
559 "Set filename for remote session recording.\n\
560 This file is used to record the remote session for future playback\n\
561 by gdbserver.", &setlist
),
564 add_show_from_set (add_set_enum_cmd ("remotelogbase", no_class
,
566 (char *)&serial_logbase
,