15796c8dcSSimon Schubert /* Generic serial interface routines
25796c8dcSSimon Schubert
3*ef5ccd6cSJohn Marino Copyright (C) 1992-2013 Free Software Foundation, Inc.
45796c8dcSSimon Schubert
55796c8dcSSimon Schubert This file is part of GDB.
65796c8dcSSimon Schubert
75796c8dcSSimon Schubert This program is free software; you can redistribute it and/or modify
85796c8dcSSimon Schubert it under the terms of the GNU General Public License as published by
95796c8dcSSimon Schubert the Free Software Foundation; either version 3 of the License, or
105796c8dcSSimon Schubert (at your option) any later version.
115796c8dcSSimon Schubert
125796c8dcSSimon Schubert This program is distributed in the hope that it will be useful,
135796c8dcSSimon Schubert but WITHOUT ANY WARRANTY; without even the implied warranty of
145796c8dcSSimon Schubert MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
155796c8dcSSimon Schubert GNU General Public License for more details.
165796c8dcSSimon Schubert
175796c8dcSSimon Schubert You should have received a copy of the GNU General Public License
185796c8dcSSimon Schubert along with this program. If not, see <http://www.gnu.org/licenses/>. */
195796c8dcSSimon Schubert
205796c8dcSSimon Schubert #include "defs.h"
215796c8dcSSimon Schubert #include <ctype.h>
225796c8dcSSimon Schubert #include "serial.h"
235796c8dcSSimon Schubert #include "gdb_string.h"
245796c8dcSSimon Schubert #include "gdbcmd.h"
25*ef5ccd6cSJohn Marino #include "cli/cli-utils.h"
265796c8dcSSimon Schubert
275796c8dcSSimon Schubert extern void _initialize_serial (void);
285796c8dcSSimon Schubert
295796c8dcSSimon Schubert /* Is serial being debugged? */
305796c8dcSSimon Schubert
31*ef5ccd6cSJohn Marino static unsigned int global_serial_debug_p;
325796c8dcSSimon Schubert
33c50c785cSJohn Marino /* Linked list of serial I/O handlers. */
345796c8dcSSimon Schubert
355796c8dcSSimon Schubert static struct serial_ops *serial_ops_list = NULL;
365796c8dcSSimon Schubert
375796c8dcSSimon Schubert /* Pointer to list of scb's. */
385796c8dcSSimon Schubert
395796c8dcSSimon Schubert static struct serial *scb_base;
405796c8dcSSimon Schubert
415796c8dcSSimon Schubert /* Non-NULL gives filename which contains a recording of the remote session,
425796c8dcSSimon Schubert suitable for playback by gdbserver. */
435796c8dcSSimon Schubert
445796c8dcSSimon Schubert static char *serial_logfile = NULL;
455796c8dcSSimon Schubert static struct ui_file *serial_logfp = NULL;
465796c8dcSSimon Schubert
47c50c785cSJohn Marino static struct serial_ops *serial_interface_lookup (const char *);
48c50c785cSJohn Marino static void serial_logchar (struct ui_file *stream,
49c50c785cSJohn Marino int ch_type, int ch, int timeout);
505796c8dcSSimon Schubert static const char logbase_hex[] = "hex";
515796c8dcSSimon Schubert static const char logbase_octal[] = "octal";
525796c8dcSSimon Schubert static const char logbase_ascii[] = "ascii";
53*ef5ccd6cSJohn Marino static const char *const logbase_enums[] =
545796c8dcSSimon Schubert {logbase_hex, logbase_octal, logbase_ascii, NULL};
555796c8dcSSimon Schubert static const char *serial_logbase = logbase_ascii;
565796c8dcSSimon Schubert
575796c8dcSSimon Schubert
585796c8dcSSimon Schubert static int serial_current_type = 0;
595796c8dcSSimon Schubert
60c50c785cSJohn Marino /* Log char CH of type CHTYPE, with TIMEOUT. */
615796c8dcSSimon Schubert
625796c8dcSSimon Schubert /* Define bogus char to represent a BREAK. Should be careful to choose a value
635796c8dcSSimon Schubert that can't be confused with a normal char, or an error code. */
645796c8dcSSimon Schubert #define SERIAL_BREAK 1235
655796c8dcSSimon Schubert
665796c8dcSSimon Schubert static void
serial_logchar(struct ui_file * stream,int ch_type,int ch,int timeout)675796c8dcSSimon Schubert serial_logchar (struct ui_file *stream, int ch_type, int ch, int timeout)
685796c8dcSSimon Schubert {
695796c8dcSSimon Schubert if (ch_type != serial_current_type)
705796c8dcSSimon Schubert {
715796c8dcSSimon Schubert fprintf_unfiltered (stream, "\n%c ", ch_type);
725796c8dcSSimon Schubert serial_current_type = ch_type;
735796c8dcSSimon Schubert }
745796c8dcSSimon Schubert
755796c8dcSSimon Schubert if (serial_logbase != logbase_ascii)
765796c8dcSSimon Schubert fputc_unfiltered (' ', stream);
775796c8dcSSimon Schubert
785796c8dcSSimon Schubert switch (ch)
795796c8dcSSimon Schubert {
805796c8dcSSimon Schubert case SERIAL_TIMEOUT:
815796c8dcSSimon Schubert fprintf_unfiltered (stream, "<Timeout: %d seconds>", timeout);
825796c8dcSSimon Schubert return;
835796c8dcSSimon Schubert case SERIAL_ERROR:
845796c8dcSSimon Schubert fprintf_unfiltered (stream, "<Error: %s>", safe_strerror (errno));
855796c8dcSSimon Schubert return;
865796c8dcSSimon Schubert case SERIAL_EOF:
875796c8dcSSimon Schubert fputs_unfiltered ("<Eof>", stream);
885796c8dcSSimon Schubert return;
895796c8dcSSimon Schubert case SERIAL_BREAK:
905796c8dcSSimon Schubert fputs_unfiltered ("<Break>", stream);
915796c8dcSSimon Schubert return;
925796c8dcSSimon Schubert default:
935796c8dcSSimon Schubert if (serial_logbase == logbase_hex)
945796c8dcSSimon Schubert fprintf_unfiltered (stream, "%02x", ch & 0xff);
955796c8dcSSimon Schubert else if (serial_logbase == logbase_octal)
965796c8dcSSimon Schubert fprintf_unfiltered (stream, "%03o", ch & 0xff);
975796c8dcSSimon Schubert else
985796c8dcSSimon Schubert switch (ch)
995796c8dcSSimon Schubert {
1005796c8dcSSimon Schubert case '\\':
1015796c8dcSSimon Schubert fputs_unfiltered ("\\\\", stream);
1025796c8dcSSimon Schubert break;
1035796c8dcSSimon Schubert case '\b':
1045796c8dcSSimon Schubert fputs_unfiltered ("\\b", stream);
1055796c8dcSSimon Schubert break;
1065796c8dcSSimon Schubert case '\f':
1075796c8dcSSimon Schubert fputs_unfiltered ("\\f", stream);
1085796c8dcSSimon Schubert break;
1095796c8dcSSimon Schubert case '\n':
1105796c8dcSSimon Schubert fputs_unfiltered ("\\n", stream);
1115796c8dcSSimon Schubert break;
1125796c8dcSSimon Schubert case '\r':
1135796c8dcSSimon Schubert fputs_unfiltered ("\\r", stream);
1145796c8dcSSimon Schubert break;
1155796c8dcSSimon Schubert case '\t':
1165796c8dcSSimon Schubert fputs_unfiltered ("\\t", stream);
1175796c8dcSSimon Schubert break;
1185796c8dcSSimon Schubert case '\v':
1195796c8dcSSimon Schubert fputs_unfiltered ("\\v", stream);
1205796c8dcSSimon Schubert break;
1215796c8dcSSimon Schubert default:
122c50c785cSJohn Marino fprintf_unfiltered (stream,
123c50c785cSJohn Marino isprint (ch) ? "%c" : "\\x%02x", ch & 0xFF);
1245796c8dcSSimon Schubert break;
1255796c8dcSSimon Schubert }
1265796c8dcSSimon Schubert }
1275796c8dcSSimon Schubert }
1285796c8dcSSimon Schubert
1295796c8dcSSimon Schubert void
serial_log_command(const char * cmd)1305796c8dcSSimon Schubert serial_log_command (const char *cmd)
1315796c8dcSSimon Schubert {
1325796c8dcSSimon Schubert if (!serial_logfp)
1335796c8dcSSimon Schubert return;
1345796c8dcSSimon Schubert
1355796c8dcSSimon Schubert serial_current_type = 'c';
1365796c8dcSSimon Schubert
1375796c8dcSSimon Schubert fputs_unfiltered ("\nc ", serial_logfp);
1385796c8dcSSimon Schubert fputs_unfiltered (cmd, serial_logfp);
1395796c8dcSSimon Schubert
1405796c8dcSSimon Schubert /* Make sure that the log file is as up-to-date as possible,
1415796c8dcSSimon Schubert in case we are getting ready to dump core or something. */
1425796c8dcSSimon Schubert gdb_flush (serial_logfp);
1435796c8dcSSimon Schubert }
1445796c8dcSSimon Schubert
1455796c8dcSSimon Schubert
1465796c8dcSSimon Schubert static struct serial_ops *
serial_interface_lookup(const char * name)147c50c785cSJohn Marino serial_interface_lookup (const char *name)
1485796c8dcSSimon Schubert {
1495796c8dcSSimon Schubert struct serial_ops *ops;
1505796c8dcSSimon Schubert
1515796c8dcSSimon Schubert for (ops = serial_ops_list; ops; ops = ops->next)
1525796c8dcSSimon Schubert if (strcmp (name, ops->name) == 0)
1535796c8dcSSimon Schubert return ops;
1545796c8dcSSimon Schubert
1555796c8dcSSimon Schubert return NULL;
1565796c8dcSSimon Schubert }
1575796c8dcSSimon Schubert
1585796c8dcSSimon Schubert void
serial_add_interface(struct serial_ops * optable)1595796c8dcSSimon Schubert serial_add_interface (struct serial_ops *optable)
1605796c8dcSSimon Schubert {
1615796c8dcSSimon Schubert optable->next = serial_ops_list;
1625796c8dcSSimon Schubert serial_ops_list = optable;
1635796c8dcSSimon Schubert }
1645796c8dcSSimon Schubert
165*ef5ccd6cSJohn Marino /* Return the open serial device for FD, if found, or NULL if FD is
166*ef5ccd6cSJohn Marino not already opened. */
167*ef5ccd6cSJohn Marino
168*ef5ccd6cSJohn Marino struct serial *
serial_for_fd(int fd)169*ef5ccd6cSJohn Marino serial_for_fd (int fd)
170*ef5ccd6cSJohn Marino {
171*ef5ccd6cSJohn Marino struct serial *scb;
172*ef5ccd6cSJohn Marino
173*ef5ccd6cSJohn Marino for (scb = scb_base; scb; scb = scb->next)
174*ef5ccd6cSJohn Marino if (scb->fd == fd)
175*ef5ccd6cSJohn Marino return scb;
176*ef5ccd6cSJohn Marino
177*ef5ccd6cSJohn Marino return NULL;
178*ef5ccd6cSJohn Marino }
179*ef5ccd6cSJohn Marino
1805796c8dcSSimon Schubert /* Open up a device or a network socket, depending upon the syntax of NAME. */
1815796c8dcSSimon Schubert
1825796c8dcSSimon Schubert struct serial *
serial_open(const char * name)1835796c8dcSSimon Schubert serial_open (const char *name)
1845796c8dcSSimon Schubert {
1855796c8dcSSimon Schubert struct serial *scb;
1865796c8dcSSimon Schubert struct serial_ops *ops;
1875796c8dcSSimon Schubert const char *open_name = name;
1885796c8dcSSimon Schubert
1895796c8dcSSimon Schubert if (strcmp (name, "pc") == 0)
1905796c8dcSSimon Schubert ops = serial_interface_lookup ("pc");
1915796c8dcSSimon Schubert else if (strncmp (name, "lpt", 3) == 0)
1925796c8dcSSimon Schubert ops = serial_interface_lookup ("parallel");
1935796c8dcSSimon Schubert else if (strncmp (name, "|", 1) == 0)
1945796c8dcSSimon Schubert {
1955796c8dcSSimon Schubert ops = serial_interface_lookup ("pipe");
1965796c8dcSSimon Schubert /* Discard ``|'' and any space before the command itself. */
1975796c8dcSSimon Schubert ++open_name;
198*ef5ccd6cSJohn Marino open_name = skip_spaces_const (open_name);
1995796c8dcSSimon Schubert }
2005796c8dcSSimon Schubert /* Check for a colon, suggesting an IP address/port pair.
2015796c8dcSSimon Schubert Do this *after* checking for all the interesting prefixes. We
2025796c8dcSSimon Schubert don't want to constrain the syntax of what can follow them. */
2035796c8dcSSimon Schubert else if (strchr (name, ':'))
2045796c8dcSSimon Schubert ops = serial_interface_lookup ("tcp");
2055796c8dcSSimon Schubert else
2065796c8dcSSimon Schubert ops = serial_interface_lookup ("hardwire");
2075796c8dcSSimon Schubert
2085796c8dcSSimon Schubert if (!ops)
2095796c8dcSSimon Schubert return NULL;
2105796c8dcSSimon Schubert
2115796c8dcSSimon Schubert scb = XMALLOC (struct serial);
2125796c8dcSSimon Schubert
2135796c8dcSSimon Schubert scb->ops = ops;
2145796c8dcSSimon Schubert
2155796c8dcSSimon Schubert scb->bufcnt = 0;
2165796c8dcSSimon Schubert scb->bufp = scb->buf;
2175796c8dcSSimon Schubert scb->error_fd = -1;
218*ef5ccd6cSJohn Marino scb->refcnt = 1;
2195796c8dcSSimon Schubert
220c50c785cSJohn Marino /* `...->open (...)' would get expanded by the open(2) syscall macro. */
2215796c8dcSSimon Schubert if ((*scb->ops->open) (scb, open_name))
2225796c8dcSSimon Schubert {
2235796c8dcSSimon Schubert xfree (scb);
2245796c8dcSSimon Schubert return NULL;
2255796c8dcSSimon Schubert }
2265796c8dcSSimon Schubert
2275796c8dcSSimon Schubert scb->name = xstrdup (name);
2285796c8dcSSimon Schubert scb->next = scb_base;
2295796c8dcSSimon Schubert scb->debug_p = 0;
2305796c8dcSSimon Schubert scb->async_state = 0;
2315796c8dcSSimon Schubert scb->async_handler = NULL;
2325796c8dcSSimon Schubert scb->async_context = NULL;
2335796c8dcSSimon Schubert scb_base = scb;
2345796c8dcSSimon Schubert
2355796c8dcSSimon Schubert if (serial_logfile != NULL)
2365796c8dcSSimon Schubert {
2375796c8dcSSimon Schubert serial_logfp = gdb_fopen (serial_logfile, "w");
2385796c8dcSSimon Schubert if (serial_logfp == NULL)
2395796c8dcSSimon Schubert perror_with_name (serial_logfile);
2405796c8dcSSimon Schubert }
2415796c8dcSSimon Schubert
2425796c8dcSSimon Schubert return scb;
2435796c8dcSSimon Schubert }
2445796c8dcSSimon Schubert
245c50c785cSJohn Marino /* Open a new serial stream using a file handle, using serial
246c50c785cSJohn Marino interface ops OPS. */
247c50c785cSJohn Marino
248c50c785cSJohn Marino static struct serial *
serial_fdopen_ops(const int fd,struct serial_ops * ops)249c50c785cSJohn Marino serial_fdopen_ops (const int fd, struct serial_ops *ops)
2505796c8dcSSimon Schubert {
2515796c8dcSSimon Schubert struct serial *scb;
2525796c8dcSSimon Schubert
253c50c785cSJohn Marino if (!ops)
254c50c785cSJohn Marino {
2555796c8dcSSimon Schubert ops = serial_interface_lookup ("terminal");
2565796c8dcSSimon Schubert if (!ops)
2575796c8dcSSimon Schubert ops = serial_interface_lookup ("hardwire");
258c50c785cSJohn Marino }
2595796c8dcSSimon Schubert
2605796c8dcSSimon Schubert if (!ops)
2615796c8dcSSimon Schubert return NULL;
2625796c8dcSSimon Schubert
2635796c8dcSSimon Schubert scb = XCALLOC (1, struct serial);
2645796c8dcSSimon Schubert
2655796c8dcSSimon Schubert scb->ops = ops;
2665796c8dcSSimon Schubert
2675796c8dcSSimon Schubert scb->bufcnt = 0;
2685796c8dcSSimon Schubert scb->bufp = scb->buf;
269c50c785cSJohn Marino scb->error_fd = -1;
270*ef5ccd6cSJohn Marino scb->refcnt = 1;
2715796c8dcSSimon Schubert
2725796c8dcSSimon Schubert scb->name = NULL;
2735796c8dcSSimon Schubert scb->next = scb_base;
2745796c8dcSSimon Schubert scb->debug_p = 0;
2755796c8dcSSimon Schubert scb->async_state = 0;
2765796c8dcSSimon Schubert scb->async_handler = NULL;
2775796c8dcSSimon Schubert scb->async_context = NULL;
2785796c8dcSSimon Schubert scb_base = scb;
2795796c8dcSSimon Schubert
280c50c785cSJohn Marino if ((ops->fdopen) != NULL)
281c50c785cSJohn Marino (*ops->fdopen) (scb, fd);
282c50c785cSJohn Marino else
283c50c785cSJohn Marino scb->fd = fd;
284c50c785cSJohn Marino
2855796c8dcSSimon Schubert return scb;
2865796c8dcSSimon Schubert }
2875796c8dcSSimon Schubert
288c50c785cSJohn Marino struct serial *
serial_fdopen(const int fd)289c50c785cSJohn Marino serial_fdopen (const int fd)
290c50c785cSJohn Marino {
291c50c785cSJohn Marino return serial_fdopen_ops (fd, NULL);
292c50c785cSJohn Marino }
293c50c785cSJohn Marino
2945796c8dcSSimon Schubert static void
do_serial_close(struct serial * scb,int really_close)2955796c8dcSSimon Schubert do_serial_close (struct serial *scb, int really_close)
2965796c8dcSSimon Schubert {
2975796c8dcSSimon Schubert struct serial *tmp_scb;
2985796c8dcSSimon Schubert
2995796c8dcSSimon Schubert if (serial_logfp)
3005796c8dcSSimon Schubert {
3015796c8dcSSimon Schubert fputs_unfiltered ("\nEnd of log\n", serial_logfp);
3025796c8dcSSimon Schubert serial_current_type = 0;
3035796c8dcSSimon Schubert
3045796c8dcSSimon Schubert /* XXX - What if serial_logfp == gdb_stdout or gdb_stderr? */
3055796c8dcSSimon Schubert ui_file_delete (serial_logfp);
3065796c8dcSSimon Schubert serial_logfp = NULL;
3075796c8dcSSimon Schubert }
3085796c8dcSSimon Schubert
309c50c785cSJohn Marino /* ensure that the FD has been taken out of async mode. */
3105796c8dcSSimon Schubert if (scb->async_handler != NULL)
3115796c8dcSSimon Schubert serial_async (scb, NULL, NULL);
3125796c8dcSSimon Schubert
3135796c8dcSSimon Schubert if (really_close)
3145796c8dcSSimon Schubert scb->ops->close (scb);
3155796c8dcSSimon Schubert
3165796c8dcSSimon Schubert if (scb->name)
3175796c8dcSSimon Schubert xfree (scb->name);
3185796c8dcSSimon Schubert
319*ef5ccd6cSJohn Marino /* For serial_is_open. */
320*ef5ccd6cSJohn Marino scb->bufp = NULL;
321*ef5ccd6cSJohn Marino
3225796c8dcSSimon Schubert if (scb_base == scb)
3235796c8dcSSimon Schubert scb_base = scb_base->next;
3245796c8dcSSimon Schubert else
3255796c8dcSSimon Schubert for (tmp_scb = scb_base; tmp_scb; tmp_scb = tmp_scb->next)
3265796c8dcSSimon Schubert {
3275796c8dcSSimon Schubert if (tmp_scb->next != scb)
3285796c8dcSSimon Schubert continue;
3295796c8dcSSimon Schubert
3305796c8dcSSimon Schubert tmp_scb->next = tmp_scb->next->next;
3315796c8dcSSimon Schubert break;
3325796c8dcSSimon Schubert }
3335796c8dcSSimon Schubert
334*ef5ccd6cSJohn Marino serial_unref (scb);
3355796c8dcSSimon Schubert }
3365796c8dcSSimon Schubert
3375796c8dcSSimon Schubert void
serial_close(struct serial * scb)3385796c8dcSSimon Schubert serial_close (struct serial *scb)
3395796c8dcSSimon Schubert {
3405796c8dcSSimon Schubert do_serial_close (scb, 1);
3415796c8dcSSimon Schubert }
3425796c8dcSSimon Schubert
3435796c8dcSSimon Schubert void
serial_un_fdopen(struct serial * scb)3445796c8dcSSimon Schubert serial_un_fdopen (struct serial *scb)
3455796c8dcSSimon Schubert {
3465796c8dcSSimon Schubert do_serial_close (scb, 0);
3475796c8dcSSimon Schubert }
3485796c8dcSSimon Schubert
3495796c8dcSSimon Schubert int
serial_is_open(struct serial * scb)350*ef5ccd6cSJohn Marino serial_is_open (struct serial *scb)
351*ef5ccd6cSJohn Marino {
352*ef5ccd6cSJohn Marino return scb->bufp != NULL;
353*ef5ccd6cSJohn Marino }
354*ef5ccd6cSJohn Marino
355*ef5ccd6cSJohn Marino void
serial_ref(struct serial * scb)356*ef5ccd6cSJohn Marino serial_ref (struct serial *scb)
357*ef5ccd6cSJohn Marino {
358*ef5ccd6cSJohn Marino scb->refcnt++;
359*ef5ccd6cSJohn Marino }
360*ef5ccd6cSJohn Marino
361*ef5ccd6cSJohn Marino void
serial_unref(struct serial * scb)362*ef5ccd6cSJohn Marino serial_unref (struct serial *scb)
363*ef5ccd6cSJohn Marino {
364*ef5ccd6cSJohn Marino --scb->refcnt;
365*ef5ccd6cSJohn Marino if (scb->refcnt == 0)
366*ef5ccd6cSJohn Marino xfree (scb);
367*ef5ccd6cSJohn Marino }
368*ef5ccd6cSJohn Marino
369*ef5ccd6cSJohn Marino int
serial_readchar(struct serial * scb,int timeout)3705796c8dcSSimon Schubert serial_readchar (struct serial *scb, int timeout)
3715796c8dcSSimon Schubert {
3725796c8dcSSimon Schubert int ch;
3735796c8dcSSimon Schubert
3745796c8dcSSimon Schubert /* FIXME: cagney/1999-10-11: Don't enable this check until the ASYNC
3755796c8dcSSimon Schubert code is finished. */
3765796c8dcSSimon Schubert if (0 && serial_is_async_p (scb) && timeout < 0)
3775796c8dcSSimon Schubert internal_error (__FILE__, __LINE__,
3785796c8dcSSimon Schubert _("serial_readchar: blocking read in async mode"));
3795796c8dcSSimon Schubert
3805796c8dcSSimon Schubert ch = scb->ops->readchar (scb, timeout);
3815796c8dcSSimon Schubert if (serial_logfp != NULL)
3825796c8dcSSimon Schubert {
3835796c8dcSSimon Schubert serial_logchar (serial_logfp, 'r', ch, timeout);
3845796c8dcSSimon Schubert
3855796c8dcSSimon Schubert /* Make sure that the log file is as up-to-date as possible,
3865796c8dcSSimon Schubert in case we are getting ready to dump core or something. */
3875796c8dcSSimon Schubert gdb_flush (serial_logfp);
3885796c8dcSSimon Schubert }
3895796c8dcSSimon Schubert if (serial_debug_p (scb))
3905796c8dcSSimon Schubert {
3915796c8dcSSimon Schubert fprintf_unfiltered (gdb_stdlog, "[");
3925796c8dcSSimon Schubert serial_logchar (gdb_stdlog, 'r', ch, timeout);
3935796c8dcSSimon Schubert fprintf_unfiltered (gdb_stdlog, "]");
3945796c8dcSSimon Schubert gdb_flush (gdb_stdlog);
3955796c8dcSSimon Schubert }
3965796c8dcSSimon Schubert
3975796c8dcSSimon Schubert return (ch);
3985796c8dcSSimon Schubert }
3995796c8dcSSimon Schubert
4005796c8dcSSimon Schubert int
serial_write(struct serial * scb,const char * str,int len)4015796c8dcSSimon Schubert serial_write (struct serial *scb, const char *str, int len)
4025796c8dcSSimon Schubert {
4035796c8dcSSimon Schubert if (serial_logfp != NULL)
4045796c8dcSSimon Schubert {
4055796c8dcSSimon Schubert int count;
4065796c8dcSSimon Schubert
4075796c8dcSSimon Schubert for (count = 0; count < len; count++)
4085796c8dcSSimon Schubert serial_logchar (serial_logfp, 'w', str[count] & 0xff, 0);
4095796c8dcSSimon Schubert
4105796c8dcSSimon Schubert /* Make sure that the log file is as up-to-date as possible,
4115796c8dcSSimon Schubert in case we are getting ready to dump core or something. */
4125796c8dcSSimon Schubert gdb_flush (serial_logfp);
4135796c8dcSSimon Schubert }
414cf7f2e2dSJohn Marino if (serial_debug_p (scb))
415cf7f2e2dSJohn Marino {
416cf7f2e2dSJohn Marino int count;
417cf7f2e2dSJohn Marino
418cf7f2e2dSJohn Marino for (count = 0; count < len; count++)
419cf7f2e2dSJohn Marino {
420cf7f2e2dSJohn Marino fprintf_unfiltered (gdb_stdlog, "[");
421cf7f2e2dSJohn Marino serial_logchar (gdb_stdlog, 'w', str[count] & 0xff, 0);
422cf7f2e2dSJohn Marino fprintf_unfiltered (gdb_stdlog, "]");
423cf7f2e2dSJohn Marino }
424cf7f2e2dSJohn Marino gdb_flush (gdb_stdlog);
425cf7f2e2dSJohn Marino }
4265796c8dcSSimon Schubert
4275796c8dcSSimon Schubert return (scb->ops->write (scb, str, len));
4285796c8dcSSimon Schubert }
4295796c8dcSSimon Schubert
4305796c8dcSSimon Schubert void
serial_printf(struct serial * desc,const char * format,...)4315796c8dcSSimon Schubert serial_printf (struct serial *desc, const char *format,...)
4325796c8dcSSimon Schubert {
4335796c8dcSSimon Schubert va_list args;
4345796c8dcSSimon Schubert char *buf;
4355796c8dcSSimon Schubert va_start (args, format);
4365796c8dcSSimon Schubert
4375796c8dcSSimon Schubert buf = xstrvprintf (format, args);
4385796c8dcSSimon Schubert serial_write (desc, buf, strlen (buf));
4395796c8dcSSimon Schubert
4405796c8dcSSimon Schubert xfree (buf);
4415796c8dcSSimon Schubert va_end (args);
4425796c8dcSSimon Schubert }
4435796c8dcSSimon Schubert
4445796c8dcSSimon Schubert int
serial_drain_output(struct serial * scb)4455796c8dcSSimon Schubert serial_drain_output (struct serial *scb)
4465796c8dcSSimon Schubert {
4475796c8dcSSimon Schubert return scb->ops->drain_output (scb);
4485796c8dcSSimon Schubert }
4495796c8dcSSimon Schubert
4505796c8dcSSimon Schubert int
serial_flush_output(struct serial * scb)4515796c8dcSSimon Schubert serial_flush_output (struct serial *scb)
4525796c8dcSSimon Schubert {
4535796c8dcSSimon Schubert return scb->ops->flush_output (scb);
4545796c8dcSSimon Schubert }
4555796c8dcSSimon Schubert
4565796c8dcSSimon Schubert int
serial_flush_input(struct serial * scb)4575796c8dcSSimon Schubert serial_flush_input (struct serial *scb)
4585796c8dcSSimon Schubert {
4595796c8dcSSimon Schubert return scb->ops->flush_input (scb);
4605796c8dcSSimon Schubert }
4615796c8dcSSimon Schubert
4625796c8dcSSimon Schubert int
serial_send_break(struct serial * scb)4635796c8dcSSimon Schubert serial_send_break (struct serial *scb)
4645796c8dcSSimon Schubert {
4655796c8dcSSimon Schubert if (serial_logfp != NULL)
4665796c8dcSSimon Schubert serial_logchar (serial_logfp, 'w', SERIAL_BREAK, 0);
4675796c8dcSSimon Schubert
4685796c8dcSSimon Schubert return (scb->ops->send_break (scb));
4695796c8dcSSimon Schubert }
4705796c8dcSSimon Schubert
4715796c8dcSSimon Schubert void
serial_raw(struct serial * scb)4725796c8dcSSimon Schubert serial_raw (struct serial *scb)
4735796c8dcSSimon Schubert {
4745796c8dcSSimon Schubert scb->ops->go_raw (scb);
4755796c8dcSSimon Schubert }
4765796c8dcSSimon Schubert
4775796c8dcSSimon Schubert serial_ttystate
serial_get_tty_state(struct serial * scb)4785796c8dcSSimon Schubert serial_get_tty_state (struct serial *scb)
4795796c8dcSSimon Schubert {
4805796c8dcSSimon Schubert return scb->ops->get_tty_state (scb);
4815796c8dcSSimon Schubert }
4825796c8dcSSimon Schubert
483c50c785cSJohn Marino serial_ttystate
serial_copy_tty_state(struct serial * scb,serial_ttystate ttystate)484c50c785cSJohn Marino serial_copy_tty_state (struct serial *scb, serial_ttystate ttystate)
485c50c785cSJohn Marino {
486c50c785cSJohn Marino return scb->ops->copy_tty_state (scb, ttystate);
487c50c785cSJohn Marino }
488c50c785cSJohn Marino
4895796c8dcSSimon Schubert int
serial_set_tty_state(struct serial * scb,serial_ttystate ttystate)4905796c8dcSSimon Schubert serial_set_tty_state (struct serial *scb, serial_ttystate ttystate)
4915796c8dcSSimon Schubert {
4925796c8dcSSimon Schubert return scb->ops->set_tty_state (scb, ttystate);
4935796c8dcSSimon Schubert }
4945796c8dcSSimon Schubert
4955796c8dcSSimon Schubert void
serial_print_tty_state(struct serial * scb,serial_ttystate ttystate,struct ui_file * stream)4965796c8dcSSimon Schubert serial_print_tty_state (struct serial *scb,
4975796c8dcSSimon Schubert serial_ttystate ttystate,
4985796c8dcSSimon Schubert struct ui_file *stream)
4995796c8dcSSimon Schubert {
5005796c8dcSSimon Schubert scb->ops->print_tty_state (scb, ttystate, stream);
5015796c8dcSSimon Schubert }
5025796c8dcSSimon Schubert
5035796c8dcSSimon Schubert int
serial_noflush_set_tty_state(struct serial * scb,serial_ttystate new_ttystate,serial_ttystate old_ttystate)5045796c8dcSSimon Schubert serial_noflush_set_tty_state (struct serial *scb,
5055796c8dcSSimon Schubert serial_ttystate new_ttystate,
5065796c8dcSSimon Schubert serial_ttystate old_ttystate)
5075796c8dcSSimon Schubert {
5085796c8dcSSimon Schubert return scb->ops->noflush_set_tty_state (scb, new_ttystate, old_ttystate);
5095796c8dcSSimon Schubert }
5105796c8dcSSimon Schubert
5115796c8dcSSimon Schubert int
serial_setbaudrate(struct serial * scb,int rate)5125796c8dcSSimon Schubert serial_setbaudrate (struct serial *scb, int rate)
5135796c8dcSSimon Schubert {
5145796c8dcSSimon Schubert return scb->ops->setbaudrate (scb, rate);
5155796c8dcSSimon Schubert }
5165796c8dcSSimon Schubert
5175796c8dcSSimon Schubert int
serial_setstopbits(struct serial * scb,int num)5185796c8dcSSimon Schubert serial_setstopbits (struct serial *scb, int num)
5195796c8dcSSimon Schubert {
5205796c8dcSSimon Schubert return scb->ops->setstopbits (scb, num);
5215796c8dcSSimon Schubert }
5225796c8dcSSimon Schubert
5235796c8dcSSimon Schubert int
serial_can_async_p(struct serial * scb)5245796c8dcSSimon Schubert serial_can_async_p (struct serial *scb)
5255796c8dcSSimon Schubert {
5265796c8dcSSimon Schubert return (scb->ops->async != NULL);
5275796c8dcSSimon Schubert }
5285796c8dcSSimon Schubert
5295796c8dcSSimon Schubert int
serial_is_async_p(struct serial * scb)5305796c8dcSSimon Schubert serial_is_async_p (struct serial *scb)
5315796c8dcSSimon Schubert {
5325796c8dcSSimon Schubert return (scb->ops->async != NULL) && (scb->async_handler != NULL);
5335796c8dcSSimon Schubert }
5345796c8dcSSimon Schubert
5355796c8dcSSimon Schubert void
serial_async(struct serial * scb,serial_event_ftype * handler,void * context)5365796c8dcSSimon Schubert serial_async (struct serial *scb,
5375796c8dcSSimon Schubert serial_event_ftype *handler,
5385796c8dcSSimon Schubert void *context)
5395796c8dcSSimon Schubert {
5405796c8dcSSimon Schubert int changed = ((scb->async_handler == NULL) != (handler == NULL));
541cf7f2e2dSJohn Marino
5425796c8dcSSimon Schubert scb->async_handler = handler;
5435796c8dcSSimon Schubert scb->async_context = context;
5445796c8dcSSimon Schubert /* Only change mode if there is a need. */
5455796c8dcSSimon Schubert if (changed)
5465796c8dcSSimon Schubert scb->ops->async (scb, handler != NULL);
5475796c8dcSSimon Schubert }
5485796c8dcSSimon Schubert
5495796c8dcSSimon Schubert void
serial_debug(struct serial * scb,int debug_p)5505796c8dcSSimon Schubert serial_debug (struct serial *scb, int debug_p)
5515796c8dcSSimon Schubert {
5525796c8dcSSimon Schubert scb->debug_p = debug_p;
5535796c8dcSSimon Schubert }
5545796c8dcSSimon Schubert
5555796c8dcSSimon Schubert int
serial_debug_p(struct serial * scb)5565796c8dcSSimon Schubert serial_debug_p (struct serial *scb)
5575796c8dcSSimon Schubert {
5585796c8dcSSimon Schubert return scb->debug_p || global_serial_debug_p;
5595796c8dcSSimon Schubert }
5605796c8dcSSimon Schubert
5615796c8dcSSimon Schubert #ifdef USE_WIN32API
5625796c8dcSSimon Schubert void
serial_wait_handle(struct serial * scb,HANDLE * read,HANDLE * except)5635796c8dcSSimon Schubert serial_wait_handle (struct serial *scb, HANDLE *read, HANDLE *except)
5645796c8dcSSimon Schubert {
5655796c8dcSSimon Schubert if (scb->ops->wait_handle)
5665796c8dcSSimon Schubert scb->ops->wait_handle (scb, read, except);
5675796c8dcSSimon Schubert else
5685796c8dcSSimon Schubert {
5695796c8dcSSimon Schubert *read = (HANDLE) _get_osfhandle (scb->fd);
5705796c8dcSSimon Schubert *except = NULL;
5715796c8dcSSimon Schubert }
5725796c8dcSSimon Schubert }
5735796c8dcSSimon Schubert
5745796c8dcSSimon Schubert void
serial_done_wait_handle(struct serial * scb)5755796c8dcSSimon Schubert serial_done_wait_handle (struct serial *scb)
5765796c8dcSSimon Schubert {
5775796c8dcSSimon Schubert if (scb->ops->done_wait_handle)
5785796c8dcSSimon Schubert scb->ops->done_wait_handle (scb);
5795796c8dcSSimon Schubert }
5805796c8dcSSimon Schubert #endif
5815796c8dcSSimon Schubert
582c50c785cSJohn Marino int
serial_pipe(struct serial * scbs[2])583c50c785cSJohn Marino serial_pipe (struct serial *scbs[2])
584c50c785cSJohn Marino {
585c50c785cSJohn Marino struct serial_ops *ops;
586c50c785cSJohn Marino int fildes[2];
587c50c785cSJohn Marino
588c50c785cSJohn Marino ops = serial_interface_lookup ("pipe");
589c50c785cSJohn Marino if (!ops)
590c50c785cSJohn Marino {
591c50c785cSJohn Marino errno = ENOSYS;
592c50c785cSJohn Marino return -1;
593c50c785cSJohn Marino }
594c50c785cSJohn Marino
595c50c785cSJohn Marino if (gdb_pipe (fildes) == -1)
596c50c785cSJohn Marino return -1;
597c50c785cSJohn Marino
598c50c785cSJohn Marino scbs[0] = serial_fdopen_ops (fildes[0], ops);
599c50c785cSJohn Marino scbs[1] = serial_fdopen_ops (fildes[1], ops);
600c50c785cSJohn Marino return 0;
601c50c785cSJohn Marino }
602c50c785cSJohn Marino
6035796c8dcSSimon Schubert /* Serial set/show framework. */
6045796c8dcSSimon Schubert
6055796c8dcSSimon Schubert static struct cmd_list_element *serial_set_cmdlist;
6065796c8dcSSimon Schubert static struct cmd_list_element *serial_show_cmdlist;
6075796c8dcSSimon Schubert
6085796c8dcSSimon Schubert static void
serial_set_cmd(char * args,int from_tty)6095796c8dcSSimon Schubert serial_set_cmd (char *args, int from_tty)
6105796c8dcSSimon Schubert {
611c50c785cSJohn Marino printf_unfiltered ("\"set serial\" must be followed "
612c50c785cSJohn Marino "by the name of a command.\n");
6135796c8dcSSimon Schubert help_list (serial_set_cmdlist, "set serial ", -1, gdb_stdout);
6145796c8dcSSimon Schubert }
6155796c8dcSSimon Schubert
6165796c8dcSSimon Schubert static void
serial_show_cmd(char * args,int from_tty)6175796c8dcSSimon Schubert serial_show_cmd (char *args, int from_tty)
6185796c8dcSSimon Schubert {
6195796c8dcSSimon Schubert cmd_show_list (serial_show_cmdlist, from_tty, "");
6205796c8dcSSimon Schubert }
6215796c8dcSSimon Schubert
6225796c8dcSSimon Schubert
6235796c8dcSSimon Schubert void
_initialize_serial(void)6245796c8dcSSimon Schubert _initialize_serial (void)
6255796c8dcSSimon Schubert {
6265796c8dcSSimon Schubert #if 0
6275796c8dcSSimon Schubert add_com ("connect", class_obscure, connect_command, _("\
6285796c8dcSSimon Schubert Connect the terminal directly up to the command monitor.\n\
6295796c8dcSSimon Schubert Use <CR>~. or <CR>~^D to break out."));
6305796c8dcSSimon Schubert #endif /* 0 */
6315796c8dcSSimon Schubert
6325796c8dcSSimon Schubert add_prefix_cmd ("serial", class_maintenance, serial_set_cmd, _("\
6335796c8dcSSimon Schubert Set default serial/parallel port configuration."),
6345796c8dcSSimon Schubert &serial_set_cmdlist, "set serial ",
6355796c8dcSSimon Schubert 0/*allow-unknown*/,
6365796c8dcSSimon Schubert &setlist);
6375796c8dcSSimon Schubert
6385796c8dcSSimon Schubert add_prefix_cmd ("serial", class_maintenance, serial_show_cmd, _("\
6395796c8dcSSimon Schubert Show default serial/parallel port configuration."),
6405796c8dcSSimon Schubert &serial_show_cmdlist, "show serial ",
6415796c8dcSSimon Schubert 0/*allow-unknown*/,
6425796c8dcSSimon Schubert &showlist);
6435796c8dcSSimon Schubert
6445796c8dcSSimon Schubert add_setshow_filename_cmd ("remotelogfile", no_class, &serial_logfile, _("\
6455796c8dcSSimon Schubert Set filename for remote session recording."), _("\
6465796c8dcSSimon Schubert Show filename for remote session recording."), _("\
6475796c8dcSSimon Schubert This file is used to record the remote session for future playback\n\
6485796c8dcSSimon Schubert by gdbserver."),
6495796c8dcSSimon Schubert NULL,
6505796c8dcSSimon Schubert NULL, /* FIXME: i18n: */
6515796c8dcSSimon Schubert &setlist, &showlist);
6525796c8dcSSimon Schubert
6535796c8dcSSimon Schubert add_setshow_enum_cmd ("remotelogbase", no_class, logbase_enums,
6545796c8dcSSimon Schubert &serial_logbase, _("\
6555796c8dcSSimon Schubert Set numerical base for remote session logging"), _("\
6565796c8dcSSimon Schubert Show numerical base for remote session logging"), NULL,
6575796c8dcSSimon Schubert NULL,
6585796c8dcSSimon Schubert NULL, /* FIXME: i18n: */
6595796c8dcSSimon Schubert &setlist, &showlist);
6605796c8dcSSimon Schubert
661*ef5ccd6cSJohn Marino add_setshow_zuinteger_cmd ("serial", class_maintenance,
6625796c8dcSSimon Schubert &global_serial_debug_p, _("\
6635796c8dcSSimon Schubert Set serial debugging."), _("\
6645796c8dcSSimon Schubert Show serial debugging."), _("\
6655796c8dcSSimon Schubert When non-zero, serial port debugging is enabled."),
6665796c8dcSSimon Schubert NULL,
6675796c8dcSSimon Schubert NULL, /* FIXME: i18n: */
6685796c8dcSSimon Schubert &setdebuglist, &showdebuglist);
6695796c8dcSSimon Schubert }
670