* wrapper.c (sim_create_inferior): Treat WMMX2 binaries as iWMMXt
[deliverable/binutils-gdb.git] / gdb / serial.c
CommitLineData
c906108c 1/* Generic serial interface routines
4fcf66da 2
0b302171 3 Copyright (C) 1992-2002, 2004-2012 Free Software Foundation, Inc.
c906108c 4
c5aa993b 5 This file is part of GDB.
c906108c 6
c5aa993b
JM
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
a9762ec7 9 the Free Software Foundation; either version 3 of the License, or
c5aa993b 10 (at your option) any later version.
c906108c 11
c5aa993b
JM
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
c906108c 16
c5aa993b 17 You should have received a copy of the GNU General Public License
a9762ec7 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
c906108c
SS
19
20#include "defs.h"
21#include <ctype.h>
22#include "serial.h"
23#include "gdb_string.h"
24#include "gdbcmd.h"
25
c2c6d25f 26extern void _initialize_serial (void);
392a587b 27
c378eb4e 28/* Is serial being debugged? */
2acceee2
JM
29
30static int global_serial_debug_p;
31
c378eb4e 32/* Linked list of serial I/O handlers. */
c906108c
SS
33
34static struct serial_ops *serial_ops_list = NULL;
35
c906108c 36/* Non-NULL gives filename which contains a recording of the remote session,
c378eb4e 37 suitable for playback by gdbserver. */
c906108c
SS
38
39static char *serial_logfile = NULL;
d9fcf2fb 40static struct ui_file *serial_logfp = NULL;
c906108c 41
58f07bae 42static struct serial_ops *serial_interface_lookup (const char *);
3e43a32a
MS
43static void serial_logchar (struct ui_file *stream,
44 int ch_type, int ch, int timeout);
53904c9e
AC
45static const char logbase_hex[] = "hex";
46static const char logbase_octal[] = "octal";
47static const char logbase_ascii[] = "ascii";
40478521 48static const char *const logbase_enums[] =
c5aa993b 49{logbase_hex, logbase_octal, logbase_ascii, NULL};
53904c9e 50static const char *serial_logbase = logbase_ascii;
c906108c 51\f
c5aa993b 52
c906108c
SS
53static int serial_current_type = 0;
54
c378eb4e 55/* Log char CH of type CHTYPE, with TIMEOUT. */
c906108c
SS
56
57/* Define bogus char to represent a BREAK. Should be careful to choose a value
58 that can't be confused with a normal char, or an error code. */
59#define SERIAL_BREAK 1235
60
61static void
d9fcf2fb 62serial_logchar (struct ui_file *stream, int ch_type, int ch, int timeout)
c906108c
SS
63{
64 if (ch_type != serial_current_type)
65 {
2acceee2 66 fprintf_unfiltered (stream, "\n%c ", ch_type);
c906108c
SS
67 serial_current_type = ch_type;
68 }
69
70 if (serial_logbase != logbase_ascii)
2acceee2 71 fputc_unfiltered (' ', stream);
c906108c
SS
72
73 switch (ch)
74 {
75 case SERIAL_TIMEOUT:
2acceee2 76 fprintf_unfiltered (stream, "<Timeout: %d seconds>", timeout);
c906108c
SS
77 return;
78 case SERIAL_ERROR:
2acceee2 79 fprintf_unfiltered (stream, "<Error: %s>", safe_strerror (errno));
c906108c
SS
80 return;
81 case SERIAL_EOF:
2acceee2 82 fputs_unfiltered ("<Eof>", stream);
c906108c
SS
83 return;
84 case SERIAL_BREAK:
2acceee2 85 fputs_unfiltered ("<Break>", stream);
c906108c
SS
86 return;
87 default:
88 if (serial_logbase == logbase_hex)
2acceee2 89 fprintf_unfiltered (stream, "%02x", ch & 0xff);
c906108c 90 else if (serial_logbase == logbase_octal)
2acceee2 91 fprintf_unfiltered (stream, "%03o", ch & 0xff);
c906108c
SS
92 else
93 switch (ch)
94 {
c5aa993b 95 case '\\':
2acceee2 96 fputs_unfiltered ("\\\\", stream);
c5aa993b
JM
97 break;
98 case '\b':
2acceee2 99 fputs_unfiltered ("\\b", stream);
c5aa993b
JM
100 break;
101 case '\f':
2acceee2 102 fputs_unfiltered ("\\f", stream);
c5aa993b
JM
103 break;
104 case '\n':
2acceee2 105 fputs_unfiltered ("\\n", stream);
c5aa993b
JM
106 break;
107 case '\r':
2acceee2 108 fputs_unfiltered ("\\r", stream);
c5aa993b
JM
109 break;
110 case '\t':
2acceee2 111 fputs_unfiltered ("\\t", stream);
c5aa993b
JM
112 break;
113 case '\v':
2acceee2 114 fputs_unfiltered ("\\v", stream);
c5aa993b
JM
115 break;
116 default:
3e43a32a
MS
117 fprintf_unfiltered (stream,
118 isprint (ch) ? "%c" : "\\x%02x", ch & 0xFF);
c5aa993b 119 break;
c906108c
SS
120 }
121 }
122}
123
124void
c2c6d25f 125serial_log_command (const char *cmd)
c906108c
SS
126{
127 if (!serial_logfp)
128 return;
129
130 serial_current_type = 'c';
131
132 fputs_unfiltered ("\nc ", serial_logfp);
133 fputs_unfiltered (cmd, serial_logfp);
134
135 /* Make sure that the log file is as up-to-date as possible,
c378eb4e 136 in case we are getting ready to dump core or something. */
c906108c
SS
137 gdb_flush (serial_logfp);
138}
139
c2c6d25f 140\f
c906108c 141static struct serial_ops *
58f07bae 142serial_interface_lookup (const char *name)
c906108c
SS
143{
144 struct serial_ops *ops;
145
146 for (ops = serial_ops_list; ops; ops = ops->next)
147 if (strcmp (name, ops->name) == 0)
148 return ops;
149
150 return NULL;
151}
152
153void
c2c6d25f 154serial_add_interface (struct serial_ops *optable)
c906108c
SS
155{
156 optable->next = serial_ops_list;
157 serial_ops_list = optable;
158}
159
c378eb4e 160/* Open up a device or a network socket, depending upon the syntax of NAME. */
c906108c 161
819cc324 162struct serial *
c2c6d25f 163serial_open (const char *name)
c906108c 164{
819cc324 165 struct serial *scb;
c906108c 166 struct serial_ops *ops;
c2c6d25f 167 const char *open_name = name;
c906108c 168
50a9e2f1 169 if (strcmp (name, "pc") == 0)
c906108c 170 ops = serial_interface_lookup ("pc");
c906108c
SS
171 else if (strncmp (name, "lpt", 3) == 0)
172 ops = serial_interface_lookup ("parallel");
43e526b9 173 else if (strncmp (name, "|", 1) == 0)
c2c6d25f
JM
174 {
175 ops = serial_interface_lookup ("pipe");
8b9e3a15
VP
176 /* Discard ``|'' and any space before the command itself. */
177 ++open_name;
178 while (isspace (*open_name))
179 ++open_name;
c2c6d25f 180 }
2821caf1
JB
181 /* Check for a colon, suggesting an IP address/port pair.
182 Do this *after* checking for all the interesting prefixes. We
183 don't want to constrain the syntax of what can follow them. */
184 else if (strchr (name, ':'))
185 ops = serial_interface_lookup ("tcp");
c906108c
SS
186 else
187 ops = serial_interface_lookup ("hardwire");
188
189 if (!ops)
190 return NULL;
191
65e2f740 192 scb = XMALLOC (struct serial);
c906108c
SS
193
194 scb->ops = ops;
195
196 scb->bufcnt = 0;
197 scb->bufp = scb->buf;
65cc4390 198 scb->error_fd = -1;
ddefb60f 199 scb->refcnt = 1;
c906108c 200
766062f6 201 /* `...->open (...)' would get expanded by the open(2) syscall macro. */
652aaa24 202 if ((*scb->ops->open) (scb, open_name))
c906108c 203 {
b8c9b27d 204 xfree (scb);
c906108c
SS
205 return NULL;
206 }
207
4fcf66da 208 scb->name = xstrdup (name);
2acceee2
JM
209 scb->debug_p = 0;
210 scb->async_state = 0;
c2c6d25f
JM
211 scb->async_handler = NULL;
212 scb->async_context = NULL;
c906108c
SS
213
214 if (serial_logfile != NULL)
215 {
216 serial_logfp = gdb_fopen (serial_logfile, "w");
217 if (serial_logfp == NULL)
218 perror_with_name (serial_logfile);
219 }
220
221 return scb;
222}
223
58f07bae
PA
224/* Open a new serial stream using a file handle, using serial
225 interface ops OPS. */
226
227static struct serial *
228serial_fdopen_ops (const int fd, struct serial_ops *ops)
c906108c 229{
819cc324 230 struct serial *scb;
c906108c 231
0ea3f30e 232 if (!ops)
58f07bae
PA
233 {
234 ops = serial_interface_lookup ("terminal");
235 if (!ops)
236 ops = serial_interface_lookup ("hardwire");
237 }
c906108c
SS
238
239 if (!ops)
240 return NULL;
241
0ea3f30e 242 scb = XCALLOC (1, struct serial);
c906108c
SS
243
244 scb->ops = ops;
245
246 scb->bufcnt = 0;
247 scb->bufp = scb->buf;
58f07bae 248 scb->error_fd = -1;
ddefb60f 249 scb->refcnt = 1;
c906108c
SS
250
251 scb->name = NULL;
2acceee2
JM
252 scb->debug_p = 0;
253 scb->async_state = 0;
c2c6d25f
JM
254 scb->async_handler = NULL;
255 scb->async_context = NULL;
c906108c 256
58f07bae
PA
257 if ((ops->fdopen) != NULL)
258 (*ops->fdopen) (scb, fd);
259 else
260 scb->fd = fd;
261
c906108c
SS
262 return scb;
263}
264
58f07bae
PA
265struct serial *
266serial_fdopen (const int fd)
267{
268 return serial_fdopen_ops (fd, NULL);
269}
270
c2c6d25f 271static void
819cc324 272do_serial_close (struct serial *scb, int really_close)
c906108c 273{
819cc324 274 struct serial *tmp_scb;
c906108c 275
c906108c
SS
276 if (serial_logfp)
277 {
278 fputs_unfiltered ("\nEnd of log\n", serial_logfp);
279 serial_current_type = 0;
280
c378eb4e 281 /* XXX - What if serial_logfp == gdb_stdout or gdb_stderr? */
d9fcf2fb 282 ui_file_delete (serial_logfp);
c906108c
SS
283 serial_logfp = NULL;
284 }
285
c378eb4e 286 /* ensure that the FD has been taken out of async mode. */
c2c6d25f
JM
287 if (scb->async_handler != NULL)
288 serial_async (scb, NULL, NULL);
289
c906108c
SS
290 if (really_close)
291 scb->ops->close (scb);
292
293 if (scb->name)
b8c9b27d 294 xfree (scb->name);
c906108c 295
ddefb60f
PA
296 /* For serial_is_open. */
297 scb->bufp = NULL;
298
299 serial_unref (scb);
c906108c
SS
300}
301
c2c6d25f 302void
819cc324 303serial_close (struct serial *scb)
c2c6d25f
JM
304{
305 do_serial_close (scb, 1);
306}
307
308void
819cc324 309serial_un_fdopen (struct serial *scb)
c2c6d25f
JM
310{
311 do_serial_close (scb, 0);
312}
313
ddefb60f
PA
314int
315serial_is_open (struct serial *scb)
316{
317 return scb->bufp != NULL;
318}
319
320void
321serial_ref (struct serial *scb)
322{
323 scb->refcnt++;
324}
325
326void
327serial_unref (struct serial *scb)
328{
329 --scb->refcnt;
330 if (scb->refcnt == 0)
331 xfree (scb);
332}
333
c2c6d25f 334int
819cc324 335serial_readchar (struct serial *scb, int timeout)
c2c6d25f
JM
336{
337 int ch;
338
2df3850c 339 /* FIXME: cagney/1999-10-11: Don't enable this check until the ASYNC
c378eb4e 340 code is finished. */
2cd58942 341 if (0 && serial_is_async_p (scb) && timeout < 0)
8e65ff28 342 internal_error (__FILE__, __LINE__,
e2e0b3e5 343 _("serial_readchar: blocking read in async mode"));
2df3850c 344
c2c6d25f
JM
345 ch = scb->ops->readchar (scb, timeout);
346 if (serial_logfp != NULL)
347 {
2acceee2 348 serial_logchar (serial_logfp, 'r', ch, timeout);
c2c6d25f
JM
349
350 /* Make sure that the log file is as up-to-date as possible,
c378eb4e 351 in case we are getting ready to dump core or something. */
c2c6d25f
JM
352 gdb_flush (serial_logfp);
353 }
2cd58942 354 if (serial_debug_p (scb))
2acceee2
JM
355 {
356 fprintf_unfiltered (gdb_stdlog, "[");
357 serial_logchar (gdb_stdlog, 'r', ch, timeout);
358 fprintf_unfiltered (gdb_stdlog, "]");
359 gdb_flush (gdb_stdlog);
360 }
c2c6d25f
JM
361
362 return (ch);
363}
364
365int
819cc324 366serial_write (struct serial *scb, const char *str, int len)
c2c6d25f
JM
367{
368 if (serial_logfp != NULL)
369 {
370 int count;
371
372 for (count = 0; count < len; count++)
2acceee2 373 serial_logchar (serial_logfp, 'w', str[count] & 0xff, 0);
c2c6d25f
JM
374
375 /* Make sure that the log file is as up-to-date as possible,
c378eb4e 376 in case we are getting ready to dump core or something. */
c2c6d25f
JM
377 gdb_flush (serial_logfp);
378 }
9214d371
DE
379 if (serial_debug_p (scb))
380 {
381 int count;
382
383 for (count = 0; count < len; count++)
384 {
385 fprintf_unfiltered (gdb_stdlog, "[");
386 serial_logchar (gdb_stdlog, 'w', str[count] & 0xff, 0);
387 fprintf_unfiltered (gdb_stdlog, "]");
388 }
389 gdb_flush (gdb_stdlog);
390 }
c2c6d25f
JM
391
392 return (scb->ops->write (scb, str, len));
393}
394
395void
819cc324 396serial_printf (struct serial *desc, const char *format,...)
c2c6d25f
JM
397{
398 va_list args;
399 char *buf;
400 va_start (args, format);
401
e623b504 402 buf = xstrvprintf (format, args);
2cd58942 403 serial_write (desc, buf, strlen (buf));
c2c6d25f 404
b8c9b27d 405 xfree (buf);
c2c6d25f
JM
406 va_end (args);
407}
408
409int
819cc324 410serial_drain_output (struct serial *scb)
c2c6d25f
JM
411{
412 return scb->ops->drain_output (scb);
413}
414
415int
819cc324 416serial_flush_output (struct serial *scb)
c2c6d25f
JM
417{
418 return scb->ops->flush_output (scb);
419}
420
421int
819cc324 422serial_flush_input (struct serial *scb)
c2c6d25f
JM
423{
424 return scb->ops->flush_input (scb);
425}
426
427int
819cc324 428serial_send_break (struct serial *scb)
c2c6d25f
JM
429{
430 if (serial_logfp != NULL)
2acceee2 431 serial_logchar (serial_logfp, 'w', SERIAL_BREAK, 0);
c2c6d25f
JM
432
433 return (scb->ops->send_break (scb));
434}
435
436void
819cc324 437serial_raw (struct serial *scb)
c2c6d25f
JM
438{
439 scb->ops->go_raw (scb);
440}
441
442serial_ttystate
819cc324 443serial_get_tty_state (struct serial *scb)
c2c6d25f
JM
444{
445 return scb->ops->get_tty_state (scb);
446}
447
1e182ce8
UW
448serial_ttystate
449serial_copy_tty_state (struct serial *scb, serial_ttystate ttystate)
450{
451 return scb->ops->copy_tty_state (scb, ttystate);
452}
453
c2c6d25f 454int
819cc324 455serial_set_tty_state (struct serial *scb, serial_ttystate ttystate)
c2c6d25f
JM
456{
457 return scb->ops->set_tty_state (scb, ttystate);
458}
459
460void
819cc324 461serial_print_tty_state (struct serial *scb,
c2c6d25f 462 serial_ttystate ttystate,
d9fcf2fb 463 struct ui_file *stream)
c2c6d25f
JM
464{
465 scb->ops->print_tty_state (scb, ttystate, stream);
466}
467
468int
819cc324 469serial_noflush_set_tty_state (struct serial *scb,
c2c6d25f
JM
470 serial_ttystate new_ttystate,
471 serial_ttystate old_ttystate)
472{
473 return scb->ops->noflush_set_tty_state (scb, new_ttystate, old_ttystate);
474}
475
476int
819cc324 477serial_setbaudrate (struct serial *scb, int rate)
c2c6d25f
JM
478{
479 return scb->ops->setbaudrate (scb, rate);
480}
481
482int
819cc324 483serial_setstopbits (struct serial *scb, int num)
c2c6d25f
JM
484{
485 return scb->ops->setstopbits (scb, num);
486}
487
488int
819cc324 489serial_can_async_p (struct serial *scb)
c2c6d25f
JM
490{
491 return (scb->ops->async != NULL);
492}
493
494int
819cc324 495serial_is_async_p (struct serial *scb)
c2c6d25f
JM
496{
497 return (scb->ops->async != NULL) && (scb->async_handler != NULL);
498}
499
500void
819cc324 501serial_async (struct serial *scb,
c2c6d25f
JM
502 serial_event_ftype *handler,
503 void *context)
504{
05ce04a4 505 int changed = ((scb->async_handler == NULL) != (handler == NULL));
433759f7 506
c2c6d25f
JM
507 scb->async_handler = handler;
508 scb->async_context = context;
05ce04a4
VP
509 /* Only change mode if there is a need. */
510 if (changed)
511 scb->ops->async (scb, handler != NULL);
c2c6d25f
JM
512}
513
514int
819cc324 515deprecated_serial_fd (struct serial *scb)
c2c6d25f
JM
516{
517 /* FIXME: should this output a warning that deprecated code is being
c378eb4e 518 called? */
c2c6d25f
JM
519 if (scb->fd < 0)
520 {
8e65ff28 521 internal_error (__FILE__, __LINE__,
e2e0b3e5 522 _("serial: FD not valid"));
c2c6d25f
JM
523 }
524 return scb->fd; /* sigh */
525}
526
2acceee2 527void
819cc324 528serial_debug (struct serial *scb, int debug_p)
2acceee2
JM
529{
530 scb->debug_p = debug_p;
531}
532
533int
819cc324 534serial_debug_p (struct serial *scb)
2acceee2
JM
535{
536 return scb->debug_p || global_serial_debug_p;
537}
538
0ea3f30e
DJ
539#ifdef USE_WIN32API
540void
541serial_wait_handle (struct serial *scb, HANDLE *read, HANDLE *except)
542{
543 if (scb->ops->wait_handle)
544 scb->ops->wait_handle (scb, read, except);
545 else
546 {
547 *read = (HANDLE) _get_osfhandle (scb->fd);
548 *except = NULL;
549 }
550}
c3e2b812
DJ
551
552void
553serial_done_wait_handle (struct serial *scb)
554{
555 if (scb->ops->done_wait_handle)
556 scb->ops->done_wait_handle (scb);
557}
0ea3f30e 558#endif
2acceee2 559
58f07bae
PA
560int
561serial_pipe (struct serial *scbs[2])
562{
563 struct serial_ops *ops;
564 int fildes[2];
565
566 ops = serial_interface_lookup ("pipe");
567 if (!ops)
568 {
569 errno = ENOSYS;
570 return -1;
571 }
572
573 if (gdb_pipe (fildes) == -1)
574 return -1;
575
576 scbs[0] = serial_fdopen_ops (fildes[0], ops);
577 scbs[1] = serial_fdopen_ops (fildes[1], ops);
578 return 0;
579}
580
e3abfe1d
AC
581/* Serial set/show framework. */
582
583static struct cmd_list_element *serial_set_cmdlist;
584static struct cmd_list_element *serial_show_cmdlist;
585
586static void
587serial_set_cmd (char *args, int from_tty)
588{
3e43a32a
MS
589 printf_unfiltered ("\"set serial\" must be followed "
590 "by the name of a command.\n");
e3abfe1d
AC
591 help_list (serial_set_cmdlist, "set serial ", -1, gdb_stdout);
592}
593
594static void
595serial_show_cmd (char *args, int from_tty)
596{
597 cmd_show_list (serial_show_cmdlist, from_tty, "");
598}
599
600
c906108c 601void
c2c6d25f 602_initialize_serial (void)
c906108c
SS
603{
604#if 0
1bedd215
AC
605 add_com ("connect", class_obscure, connect_command, _("\
606Connect the terminal directly up to the command monitor.\n\
607Use <CR>~. or <CR>~^D to break out."));
c906108c
SS
608#endif /* 0 */
609
1bedd215
AC
610 add_prefix_cmd ("serial", class_maintenance, serial_set_cmd, _("\
611Set default serial/parallel port configuration."),
e3abfe1d
AC
612 &serial_set_cmdlist, "set serial ",
613 0/*allow-unknown*/,
614 &setlist);
615
1bedd215
AC
616 add_prefix_cmd ("serial", class_maintenance, serial_show_cmd, _("\
617Show default serial/parallel port configuration."),
e3abfe1d
AC
618 &serial_show_cmdlist, "show serial ",
619 0/*allow-unknown*/,
620 &showlist);
621
f397e303
AC
622 add_setshow_filename_cmd ("remotelogfile", no_class, &serial_logfile, _("\
623Set filename for remote session recording."), _("\
624Show filename for remote session recording."), _("\
c906108c 625This file is used to record the remote session for future playback\n\
f397e303
AC
626by gdbserver."),
627 NULL,
628 NULL, /* FIXME: i18n: */
629 &setlist, &showlist);
c906108c 630
7ab04401
AC
631 add_setshow_enum_cmd ("remotelogbase", no_class, logbase_enums,
632 &serial_logbase, _("\
633Set numerical base for remote session logging"), _("\
634Show numerical base for remote session logging"), NULL,
635 NULL,
636 NULL, /* FIXME: i18n: */
637 &setlist, &showlist);
2acceee2 638
85c07804
AC
639 add_setshow_zinteger_cmd ("serial", class_maintenance,
640 &global_serial_debug_p, _("\
641Set serial debugging."), _("\
642Show serial debugging."), _("\
643When non-zero, serial port debugging is enabled."),
644 NULL,
645 NULL, /* FIXME: i18n: */
646 &setdebuglist, &showdebuglist);
c906108c 647}
This page took 1.091225 seconds and 4 git commands to generate.