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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-7.2/] [gdb/] [serial.c] - Blame information for rev 330

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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