OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-6.8/] [gdb/] [serial.c] - Blame information for rev 868

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 24 jeremybenn
/* Generic serial interface routines
2
 
3
   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
4
   2002, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
5
 
6
   This file is part of GDB.
7
 
8
   This program is free software; you can redistribute it and/or modify
9
   it under the terms of the GNU General Public License as published by
10
   the Free Software Foundation; either version 3 of the License, or
11
   (at your option) any later version.
12
 
13
   This program is distributed in the hope that it will be useful,
14
   but WITHOUT ANY WARRANTY; without even the implied warranty of
15
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
   GNU General Public License for more details.
17
 
18
   You should have received a copy of the GNU General Public License
19
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
20
 
21
#include "defs.h"
22
#include <ctype.h>
23
#include "serial.h"
24
#include "gdb_string.h"
25
#include "gdbcmd.h"
26
 
27
extern void _initialize_serial (void);
28
 
29
/* Is serial being debugged? */
30
 
31
static int global_serial_debug_p;
32
 
33
/* Linked list of serial I/O handlers */
34
 
35
static struct serial_ops *serial_ops_list = NULL;
36
 
37
/* This is the last serial stream opened.  Used by connect command. */
38
 
39
static struct serial *last_serial_opened = NULL;
40
 
41
/* Pointer to list of scb's. */
42
 
43
static struct serial *scb_base;
44
 
45
/* Non-NULL gives filename which contains a recording of the remote session,
46
   suitable for playback by gdbserver. */
47
 
48
static char *serial_logfile = NULL;
49
static struct ui_file *serial_logfp = NULL;
50
 
51
static struct serial_ops *serial_interface_lookup (char *);
52
static void serial_logchar (struct ui_file *stream, int ch_type, int ch, int timeout);
53
static const char logbase_hex[] = "hex";
54
static const char logbase_octal[] = "octal";
55
static const char logbase_ascii[] = "ascii";
56
static const char *logbase_enums[] =
57
{logbase_hex, logbase_octal, logbase_ascii, NULL};
58
static const char *serial_logbase = logbase_ascii;
59
 
60
 
61
static int serial_current_type = 0;
62
 
63
/* Log char CH of type CHTYPE, with TIMEOUT */
64
 
65
/* Define bogus char to represent a BREAK.  Should be careful to choose a value
66
   that can't be confused with a normal char, or an error code.  */
67
#define SERIAL_BREAK 1235
68
 
69
static void
70
serial_logchar (struct ui_file *stream, int ch_type, int ch, int timeout)
71
{
72
  if (ch_type != serial_current_type)
73
    {
74
      fprintf_unfiltered (stream, "\n%c ", ch_type);
75
      serial_current_type = ch_type;
76
    }
77
 
78
  if (serial_logbase != logbase_ascii)
79
    fputc_unfiltered (' ', stream);
80
 
81
  switch (ch)
82
    {
83
    case SERIAL_TIMEOUT:
84
      fprintf_unfiltered (stream, "<Timeout: %d seconds>", timeout);
85
      return;
86
    case SERIAL_ERROR:
87
      fprintf_unfiltered (stream, "<Error: %s>", safe_strerror (errno));
88
      return;
89
    case SERIAL_EOF:
90
      fputs_unfiltered ("<Eof>", stream);
91
      return;
92
    case SERIAL_BREAK:
93
      fputs_unfiltered ("<Break>", stream);
94
      return;
95
    default:
96
      if (serial_logbase == logbase_hex)
97
        fprintf_unfiltered (stream, "%02x", ch & 0xff);
98
      else if (serial_logbase == logbase_octal)
99
        fprintf_unfiltered (stream, "%03o", ch & 0xff);
100
      else
101
        switch (ch)
102
          {
103
          case '\\':
104
            fputs_unfiltered ("\\\\", stream);
105
            break;
106
          case '\b':
107
            fputs_unfiltered ("\\b", stream);
108
            break;
109
          case '\f':
110
            fputs_unfiltered ("\\f", stream);
111
            break;
112
          case '\n':
113
            fputs_unfiltered ("\\n", stream);
114
            break;
115
          case '\r':
116
            fputs_unfiltered ("\\r", stream);
117
            break;
118
          case '\t':
119
            fputs_unfiltered ("\\t", stream);
120
            break;
121
          case '\v':
122
            fputs_unfiltered ("\\v", stream);
123
            break;
124
          default:
125
            fprintf_unfiltered (stream, isprint (ch) ? "%c" : "\\x%02x", ch & 0xFF);
126
            break;
127
          }
128
    }
129
}
130
 
131
void
132
serial_log_command (const char *cmd)
133
{
134
  if (!serial_logfp)
135
    return;
136
 
137
  serial_current_type = 'c';
138
 
139
  fputs_unfiltered ("\nc ", serial_logfp);
140
  fputs_unfiltered (cmd, serial_logfp);
141
 
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);
145
}
146
 
147
 
148
static struct serial_ops *
149
serial_interface_lookup (char *name)
150
{
151
  struct serial_ops *ops;
152
 
153
  for (ops = serial_ops_list; ops; ops = ops->next)
154
    if (strcmp (name, ops->name) == 0)
155
      return ops;
156
 
157
  return NULL;
158
}
159
 
160
void
161
serial_add_interface (struct serial_ops *optable)
162
{
163
  optable->next = serial_ops_list;
164
  serial_ops_list = optable;
165
}
166
 
167
/* Open up a device or a network socket, depending upon the syntax of NAME. */
168
 
169
struct serial *
170
serial_open (const char *name)
171
{
172
  struct serial *scb;
173
  struct serial_ops *ops;
174
  const char *open_name = name;
175
 
176
  for (scb = scb_base; scb; scb = scb->next)
177
    if (scb->name && strcmp (scb->name, name) == 0)
178
      {
179
        scb->refcnt++;
180
        return scb;
181
      }
182
 
183
  if (strcmp (name, "pc") == 0)
184
    ops = serial_interface_lookup ("pc");
185
  else if (strncmp (name, "lpt", 3) == 0)
186
    ops = serial_interface_lookup ("parallel");
187
  else if (strncmp (name, "|", 1) == 0)
188
    {
189
      ops = serial_interface_lookup ("pipe");
190
      /* Discard ``|'' and any space before the command itself.  */
191
      ++open_name;
192
      while (isspace (*open_name))
193
        ++open_name;
194
    }
195
  /* Check for a colon, suggesting an IP address/port pair.
196
     Do this *after* checking for all the interesting prefixes.  We
197
     don't want to constrain the syntax of what can follow them.  */
198
  else if (strchr (name, ':'))
199
    ops = serial_interface_lookup ("tcp");
200
  else
201
    ops = serial_interface_lookup ("hardwire");
202
 
203
  if (!ops)
204
    return NULL;
205
 
206
  scb = XMALLOC (struct serial);
207
 
208
  scb->ops = ops;
209
 
210
  scb->bufcnt = 0;
211
  scb->bufp = scb->buf;
212
  scb->error_fd = -1;
213
 
214
  /* `...->open (...)' would get expanded by an the open(2) syscall macro.  */
215
  if ((*scb->ops->open) (scb, open_name))
216
    {
217
      xfree (scb);
218
      return NULL;
219
    }
220
 
221
  scb->name = xstrdup (name);
222
  scb->next = scb_base;
223
  scb->refcnt = 1;
224
  scb->debug_p = 0;
225
  scb->async_state = 0;
226
  scb->async_handler = NULL;
227
  scb->async_context = NULL;
228
  scb_base = scb;
229
 
230
  last_serial_opened = scb;
231
 
232
  if (serial_logfile != NULL)
233
    {
234
      serial_logfp = gdb_fopen (serial_logfile, "w");
235
      if (serial_logfp == NULL)
236
        perror_with_name (serial_logfile);
237
    }
238
 
239
  return scb;
240
}
241
 
242
/* Return the open serial device for FD, if found, or NULL if FD
243
   is not already opened.  */
244
 
245
struct serial *
246
serial_for_fd (int fd)
247
{
248
  struct serial *scb;
249
  struct serial_ops *ops;
250
 
251
  for (scb = scb_base; scb; scb = scb->next)
252
    if (scb->fd == fd)
253
      return scb;
254
 
255
  return NULL;
256
}
257
 
258
struct serial *
259
serial_fdopen (const int fd)
260
{
261
  struct serial *scb;
262
  struct serial_ops *ops;
263
 
264
  for (scb = scb_base; scb; scb = scb->next)
265
    if (scb->fd == fd)
266
      {
267
        scb->refcnt++;
268
        return scb;
269
      }
270
 
271
  ops = serial_interface_lookup ("terminal");
272
  if (!ops)
273
    ops = serial_interface_lookup ("hardwire");
274
 
275
  if (!ops)
276
    return NULL;
277
 
278
  scb = XCALLOC (1, struct serial);
279
 
280
  scb->ops = ops;
281
 
282
  scb->bufcnt = 0;
283
  scb->bufp = scb->buf;
284
 
285
  scb->fd = fd;
286
 
287
  scb->name = NULL;
288
  scb->next = scb_base;
289
  scb->refcnt = 1;
290
  scb->debug_p = 0;
291
  scb->async_state = 0;
292
  scb->async_handler = NULL;
293
  scb->async_context = NULL;
294
  scb_base = scb;
295
 
296
  last_serial_opened = scb;
297
 
298
  return scb;
299
}
300
 
301
static void
302
do_serial_close (struct serial *scb, int really_close)
303
{
304
  struct serial *tmp_scb;
305
 
306
  last_serial_opened = NULL;
307
 
308
  if (serial_logfp)
309
    {
310
      fputs_unfiltered ("\nEnd of log\n", serial_logfp);
311
      serial_current_type = 0;
312
 
313
      /* XXX - What if serial_logfp == gdb_stdout or gdb_stderr? */
314
      ui_file_delete (serial_logfp);
315
      serial_logfp = NULL;
316
    }
317
 
318
/* This is bogus.  It's not our fault if you pass us a bad scb...!  Rob, you
319
   should fix your code instead.  */
320
 
321
  if (!scb)
322
    return;
323
 
324
  scb->refcnt--;
325
  if (scb->refcnt > 0)
326
    return;
327
 
328
  /* ensure that the FD has been taken out of async mode */
329
  if (scb->async_handler != NULL)
330
    serial_async (scb, NULL, NULL);
331
 
332
  if (really_close)
333
    scb->ops->close (scb);
334
 
335
  if (scb->name)
336
    xfree (scb->name);
337
 
338
  if (scb_base == scb)
339
    scb_base = scb_base->next;
340
  else
341
    for (tmp_scb = scb_base; tmp_scb; tmp_scb = tmp_scb->next)
342
      {
343
        if (tmp_scb->next != scb)
344
          continue;
345
 
346
        tmp_scb->next = tmp_scb->next->next;
347
        break;
348
      }
349
 
350
  xfree (scb);
351
}
352
 
353
void
354
serial_close (struct serial *scb)
355
{
356
  do_serial_close (scb, 1);
357
}
358
 
359
void
360
serial_un_fdopen (struct serial *scb)
361
{
362
  do_serial_close (scb, 0);
363
}
364
 
365
int
366
serial_readchar (struct serial *scb, int timeout)
367
{
368
  int ch;
369
 
370
  /* FIXME: cagney/1999-10-11: Don't enable this check until the ASYNC
371
     code is finished. */
372
  if (0 && serial_is_async_p (scb) && timeout < 0)
373
    internal_error (__FILE__, __LINE__,
374
                    _("serial_readchar: blocking read in async mode"));
375
 
376
  ch = scb->ops->readchar (scb, timeout);
377
  if (serial_logfp != NULL)
378
    {
379
      serial_logchar (serial_logfp, 'r', ch, timeout);
380
 
381
      /* Make sure that the log file is as up-to-date as possible,
382
         in case we are getting ready to dump core or something. */
383
      gdb_flush (serial_logfp);
384
    }
385
  if (serial_debug_p (scb))
386
    {
387
      fprintf_unfiltered (gdb_stdlog, "[");
388
      serial_logchar (gdb_stdlog, 'r', ch, timeout);
389
      fprintf_unfiltered (gdb_stdlog, "]");
390
      gdb_flush (gdb_stdlog);
391
    }
392
 
393
  return (ch);
394
}
395
 
396
int
397
serial_write (struct serial *scb, const char *str, int len)
398
{
399
  if (serial_logfp != NULL)
400
    {
401
      int count;
402
 
403
      for (count = 0; count < len; count++)
404
        serial_logchar (serial_logfp, 'w', str[count] & 0xff, 0);
405
 
406
      /* Make sure that the log file is as up-to-date as possible,
407
         in case we are getting ready to dump core or something. */
408
      gdb_flush (serial_logfp);
409
    }
410
 
411
  return (scb->ops->write (scb, str, len));
412
}
413
 
414
void
415
serial_printf (struct serial *desc, const char *format,...)
416
{
417
  va_list args;
418
  char *buf;
419
  va_start (args, format);
420
 
421
  buf = xstrvprintf (format, args);
422
  serial_write (desc, buf, strlen (buf));
423
 
424
  xfree (buf);
425
  va_end (args);
426
}
427
 
428
int
429
serial_drain_output (struct serial *scb)
430
{
431
  return scb->ops->drain_output (scb);
432
}
433
 
434
int
435
serial_flush_output (struct serial *scb)
436
{
437
  return scb->ops->flush_output (scb);
438
}
439
 
440
int
441
serial_flush_input (struct serial *scb)
442
{
443
  return scb->ops->flush_input (scb);
444
}
445
 
446
int
447
serial_send_break (struct serial *scb)
448
{
449
  if (serial_logfp != NULL)
450
    serial_logchar (serial_logfp, 'w', SERIAL_BREAK, 0);
451
 
452
  return (scb->ops->send_break (scb));
453
}
454
 
455
void
456
serial_raw (struct serial *scb)
457
{
458
  scb->ops->go_raw (scb);
459
}
460
 
461
serial_ttystate
462
serial_get_tty_state (struct serial *scb)
463
{
464
  return scb->ops->get_tty_state (scb);
465
}
466
 
467
int
468
serial_set_tty_state (struct serial *scb, serial_ttystate ttystate)
469
{
470
  return scb->ops->set_tty_state (scb, ttystate);
471
}
472
 
473
void
474
serial_print_tty_state (struct serial *scb,
475
                        serial_ttystate ttystate,
476
                        struct ui_file *stream)
477
{
478
  scb->ops->print_tty_state (scb, ttystate, stream);
479
}
480
 
481
int
482
serial_noflush_set_tty_state (struct serial *scb,
483
                              serial_ttystate new_ttystate,
484
                              serial_ttystate old_ttystate)
485
{
486
  return scb->ops->noflush_set_tty_state (scb, new_ttystate, old_ttystate);
487
}
488
 
489
int
490
serial_setbaudrate (struct serial *scb, int rate)
491
{
492
  return scb->ops->setbaudrate (scb, rate);
493
}
494
 
495
int
496
serial_setstopbits (struct serial *scb, int num)
497
{
498
  return scb->ops->setstopbits (scb, num);
499
}
500
 
501
int
502
serial_can_async_p (struct serial *scb)
503
{
504
  return (scb->ops->async != NULL);
505
}
506
 
507
int
508
serial_is_async_p (struct serial *scb)
509
{
510
  return (scb->ops->async != NULL) && (scb->async_handler != NULL);
511
}
512
 
513
void
514
serial_async (struct serial *scb,
515
              serial_event_ftype *handler,
516
              void *context)
517
{
518
  int changed = ((scb->async_handler == NULL) != (handler == NULL));
519
  scb->async_handler = handler;
520
  scb->async_context = context;
521
  /* Only change mode if there is a need.  */
522
  if (changed)
523
    scb->ops->async (scb, handler != NULL);
524
}
525
 
526
int
527
deprecated_serial_fd (struct serial *scb)
528
{
529
  /* FIXME: should this output a warning that deprecated code is being
530
     called? */
531
  if (scb->fd < 0)
532
    {
533
      internal_error (__FILE__, __LINE__,
534
                      _("serial: FD not valid"));
535
    }
536
  return scb->fd; /* sigh */
537
}
538
 
539
void
540
serial_debug (struct serial *scb, int debug_p)
541
{
542
  scb->debug_p = debug_p;
543
}
544
 
545
int
546
serial_debug_p (struct serial *scb)
547
{
548
  return scb->debug_p || global_serial_debug_p;
549
}
550
 
551
#ifdef USE_WIN32API
552
void
553
serial_wait_handle (struct serial *scb, HANDLE *read, HANDLE *except)
554
{
555
  if (scb->ops->wait_handle)
556
    scb->ops->wait_handle (scb, read, except);
557
  else
558
    {
559
      *read = (HANDLE) _get_osfhandle (scb->fd);
560
      *except = NULL;
561
    }
562
}
563
 
564
void
565
serial_done_wait_handle (struct serial *scb)
566
{
567
  if (scb->ops->done_wait_handle)
568
    scb->ops->done_wait_handle (scb);
569
}
570
#endif
571
 
572
#if 0
573
/* The connect command is #if 0 because I hadn't thought of an elegant
574
   way to wait for I/O on two `struct serial *'s simultaneously.  Two
575
   solutions came to mind:
576
 
577
   1) Fork, and have have one fork handle the to user direction,
578
   and have the other hand the to target direction.  This
579
   obviously won't cut it for MSDOS.
580
 
581
   2) Use something like select.  This assumes that stdin and
582
   the target side can both be waited on via the same
583
   mechanism.  This may not be true for DOS, if GDB is
584
   talking to the target via a TCP socket.
585
   -grossman, 8 Jun 93 */
586
 
587
/* Connect the user directly to the remote system.  This command acts just like
588
   the 'cu' or 'tip' command.  Use <CR>~. or <CR>~^D to break out.  */
589
 
590
static struct serial *tty_desc; /* Controlling terminal */
591
 
592
static void
593
cleanup_tty (serial_ttystate ttystate)
594
{
595
  printf_unfiltered ("\r\n[Exiting connect mode]\r\n");
596
  serial_set_tty_state (tty_desc, ttystate);
597
  xfree (ttystate);
598
  serial_close (tty_desc);
599
}
600
 
601
static void
602
connect_command (char *args, int fromtty)
603
{
604
  int c;
605
  char cur_esc = 0;
606
  serial_ttystate ttystate;
607
  struct serial *port_desc;             /* TTY port */
608
 
609
  dont_repeat ();
610
 
611
  if (args)
612
    fprintf_unfiltered (gdb_stderr, "This command takes no args.  They have been ignored.\n");
613
 
614
  printf_unfiltered ("[Entering connect mode.  Use ~. or ~^D to escape]\n");
615
 
616
  tty_desc = serial_fdopen (0);
617
  port_desc = last_serial_opened;
618
 
619
  ttystate = serial_get_tty_state (tty_desc);
620
 
621
  serial_raw (tty_desc);
622
  serial_raw (port_desc);
623
 
624
  make_cleanup (cleanup_tty, ttystate);
625
 
626
  while (1)
627
    {
628
      int mask;
629
 
630
      mask = serial_wait_2 (tty_desc, port_desc, -1);
631
 
632
      if (mask & 2)
633
        {                       /* tty input */
634
          char cx;
635
 
636
          while (1)
637
            {
638
              c = serial_readchar (tty_desc, 0);
639
 
640
              if (c == SERIAL_TIMEOUT)
641
                break;
642
 
643
              if (c < 0)
644
                perror_with_name (_("connect"));
645
 
646
              cx = c;
647
              serial_write (port_desc, &cx, 1);
648
 
649
              switch (cur_esc)
650
                {
651
                case 0:
652
                  if (c == '\r')
653
                    cur_esc = c;
654
                  break;
655
                case '\r':
656
                  if (c == '~')
657
                    cur_esc = c;
658
                  else
659
                    cur_esc = 0;
660
                  break;
661
                case '~':
662
                  if (c == '.' || c == '\004')
663
                    return;
664
                  else
665
                    cur_esc = 0;
666
                }
667
            }
668
        }
669
 
670
      if (mask & 1)
671
        {                       /* Port input */
672
          char cx;
673
 
674
          while (1)
675
            {
676
              c = serial_readchar (port_desc, 0);
677
 
678
              if (c == SERIAL_TIMEOUT)
679
                break;
680
 
681
              if (c < 0)
682
                perror_with_name (_("connect"));
683
 
684
              cx = c;
685
 
686
              serial_write (tty_desc, &cx, 1);
687
            }
688
        }
689
    }
690
}
691
#endif /* 0 */
692
 
693
/* Serial set/show framework.  */
694
 
695
static struct cmd_list_element *serial_set_cmdlist;
696
static struct cmd_list_element *serial_show_cmdlist;
697
 
698
static void
699
serial_set_cmd (char *args, int from_tty)
700
{
701
  printf_unfiltered ("\"set serial\" must be followed by the name of a command.\n");
702
  help_list (serial_set_cmdlist, "set serial ", -1, gdb_stdout);
703
}
704
 
705
static void
706
serial_show_cmd (char *args, int from_tty)
707
{
708
  cmd_show_list (serial_show_cmdlist, from_tty, "");
709
}
710
 
711
 
712
void
713
_initialize_serial (void)
714
{
715
#if 0
716
  add_com ("connect", class_obscure, connect_command, _("\
717
Connect the terminal directly up to the command monitor.\n\
718
Use <CR>~. or <CR>~^D to break out."));
719
#endif /* 0 */
720
 
721
  add_prefix_cmd ("serial", class_maintenance, serial_set_cmd, _("\
722
Set default serial/parallel port configuration."),
723
                  &serial_set_cmdlist, "set serial ",
724
                  0/*allow-unknown*/,
725
                  &setlist);
726
 
727
  add_prefix_cmd ("serial", class_maintenance, serial_show_cmd, _("\
728
Show default serial/parallel port configuration."),
729
                  &serial_show_cmdlist, "show serial ",
730
                  0/*allow-unknown*/,
731
                  &showlist);
732
 
733
  add_setshow_filename_cmd ("remotelogfile", no_class, &serial_logfile, _("\
734
Set filename for remote session recording."), _("\
735
Show filename for remote session recording."), _("\
736
This file is used to record the remote session for future playback\n\
737
by gdbserver."),
738
                            NULL,
739
                            NULL, /* FIXME: i18n: */
740
                            &setlist, &showlist);
741
 
742
  add_setshow_enum_cmd ("remotelogbase", no_class, logbase_enums,
743
                        &serial_logbase, _("\
744
Set numerical base for remote session logging"), _("\
745
Show numerical base for remote session logging"), NULL,
746
                        NULL,
747
                        NULL, /* FIXME: i18n: */
748
                        &setlist, &showlist);
749
 
750
  add_setshow_zinteger_cmd ("serial", class_maintenance,
751
                            &global_serial_debug_p, _("\
752
Set serial debugging."), _("\
753
Show serial debugging."), _("\
754
When non-zero, serial port debugging is enabled."),
755
                            NULL,
756
                            NULL, /* FIXME: i18n: */
757
                            &setdebuglist, &showdebuglist);
758
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.