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

Subversion Repositories openrisc

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

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

Line No. Rev Author Line
1 227 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
  struct serial_ops *ops;
251
 
252
  for (scb = scb_base; scb; scb = scb->next)
253
    if (scb->fd == fd)
254
      return scb;
255
 
256
  return NULL;
257
}
258
 
259
struct serial *
260
serial_fdopen (const int fd)
261
{
262
  struct serial *scb;
263
  struct serial_ops *ops;
264
 
265
  for (scb = scb_base; scb; scb = scb->next)
266
    if (scb->fd == fd)
267
      {
268
        scb->refcnt++;
269
        return scb;
270
      }
271
 
272
  ops = serial_interface_lookup ("terminal");
273
  if (!ops)
274
    ops = serial_interface_lookup ("hardwire");
275
 
276
  if (!ops)
277
    return NULL;
278
 
279
  scb = XCALLOC (1, struct serial);
280
 
281
  scb->ops = ops;
282
 
283
  scb->bufcnt = 0;
284
  scb->bufp = scb->buf;
285
 
286
  scb->fd = fd;
287
 
288
  scb->name = NULL;
289
  scb->next = scb_base;
290
  scb->refcnt = 1;
291
  scb->debug_p = 0;
292
  scb->async_state = 0;
293
  scb->async_handler = NULL;
294
  scb->async_context = NULL;
295
  scb_base = scb;
296
 
297
  last_serial_opened = scb;
298
 
299
  return scb;
300
}
301
 
302
static void
303
do_serial_close (struct serial *scb, int really_close)
304
{
305
  struct serial *tmp_scb;
306
 
307
  last_serial_opened = NULL;
308
 
309
  if (serial_logfp)
310
    {
311
      fputs_unfiltered ("\nEnd of log\n", serial_logfp);
312
      serial_current_type = 0;
313
 
314
      /* XXX - What if serial_logfp == gdb_stdout or gdb_stderr? */
315
      ui_file_delete (serial_logfp);
316
      serial_logfp = NULL;
317
    }
318
 
319
/* This is bogus.  It's not our fault if you pass us a bad scb...!  Rob, you
320
   should fix your code instead.  */
321
 
322
  if (!scb)
323
    return;
324
 
325
  scb->refcnt--;
326
  if (scb->refcnt > 0)
327
    return;
328
 
329
  /* ensure that the FD has been taken out of async mode */
330
  if (scb->async_handler != NULL)
331
    serial_async (scb, NULL, NULL);
332
 
333
  if (really_close)
334
    scb->ops->close (scb);
335
 
336
  if (scb->name)
337
    xfree (scb->name);
338
 
339
  if (scb_base == scb)
340
    scb_base = scb_base->next;
341
  else
342
    for (tmp_scb = scb_base; tmp_scb; tmp_scb = tmp_scb->next)
343
      {
344
        if (tmp_scb->next != scb)
345
          continue;
346
 
347
        tmp_scb->next = tmp_scb->next->next;
348
        break;
349
      }
350
 
351
  xfree (scb);
352
}
353
 
354
void
355
serial_close (struct serial *scb)
356
{
357
  do_serial_close (scb, 1);
358
}
359
 
360
void
361
serial_un_fdopen (struct serial *scb)
362
{
363
  do_serial_close (scb, 0);
364
}
365
 
366
int
367
serial_readchar (struct serial *scb, int timeout)
368
{
369
  int ch;
370
 
371
  /* FIXME: cagney/1999-10-11: Don't enable this check until the ASYNC
372
     code is finished. */
373
  if (0 && serial_is_async_p (scb) && timeout < 0)
374
    internal_error (__FILE__, __LINE__,
375
                    _("serial_readchar: blocking read in async mode"));
376
 
377
  ch = scb->ops->readchar (scb, timeout);
378
  if (serial_logfp != NULL)
379
    {
380
      serial_logchar (serial_logfp, 'r', ch, timeout);
381
 
382
      /* Make sure that the log file is as up-to-date as possible,
383
         in case we are getting ready to dump core or something. */
384
      gdb_flush (serial_logfp);
385
    }
386
  if (serial_debug_p (scb))
387
    {
388
      fprintf_unfiltered (gdb_stdlog, "[");
389
      serial_logchar (gdb_stdlog, 'r', ch, timeout);
390
      fprintf_unfiltered (gdb_stdlog, "]");
391
      gdb_flush (gdb_stdlog);
392
    }
393
 
394
  return (ch);
395
}
396
 
397
int
398
serial_write (struct serial *scb, const char *str, int len)
399
{
400
  if (serial_logfp != NULL)
401
    {
402
      int count;
403
 
404
      for (count = 0; count < len; count++)
405
        serial_logchar (serial_logfp, 'w', str[count] & 0xff, 0);
406
 
407
      /* Make sure that the log file is as up-to-date as possible,
408
         in case we are getting ready to dump core or something. */
409
      gdb_flush (serial_logfp);
410
    }
411
 
412
  return (scb->ops->write (scb, str, len));
413
}
414
 
415
void
416
serial_printf (struct serial *desc, const char *format,...)
417
{
418
  va_list args;
419
  char *buf;
420
  va_start (args, format);
421
 
422
  buf = xstrvprintf (format, args);
423
  serial_write (desc, buf, strlen (buf));
424
 
425
  xfree (buf);
426
  va_end (args);
427
}
428
 
429
int
430
serial_drain_output (struct serial *scb)
431
{
432
  return scb->ops->drain_output (scb);
433
}
434
 
435
int
436
serial_flush_output (struct serial *scb)
437
{
438
  return scb->ops->flush_output (scb);
439
}
440
 
441
int
442
serial_flush_input (struct serial *scb)
443
{
444
  return scb->ops->flush_input (scb);
445
}
446
 
447
int
448
serial_send_break (struct serial *scb)
449
{
450
  if (serial_logfp != NULL)
451
    serial_logchar (serial_logfp, 'w', SERIAL_BREAK, 0);
452
 
453
  return (scb->ops->send_break (scb));
454
}
455
 
456
void
457
serial_raw (struct serial *scb)
458
{
459
  scb->ops->go_raw (scb);
460
}
461
 
462
serial_ttystate
463
serial_get_tty_state (struct serial *scb)
464
{
465
  return scb->ops->get_tty_state (scb);
466
}
467
 
468
int
469
serial_set_tty_state (struct serial *scb, serial_ttystate ttystate)
470
{
471
  return scb->ops->set_tty_state (scb, ttystate);
472
}
473
 
474
void
475
serial_print_tty_state (struct serial *scb,
476
                        serial_ttystate ttystate,
477
                        struct ui_file *stream)
478
{
479
  scb->ops->print_tty_state (scb, ttystate, stream);
480
}
481
 
482
int
483
serial_noflush_set_tty_state (struct serial *scb,
484
                              serial_ttystate new_ttystate,
485
                              serial_ttystate old_ttystate)
486
{
487
  return scb->ops->noflush_set_tty_state (scb, new_ttystate, old_ttystate);
488
}
489
 
490
int
491
serial_setbaudrate (struct serial *scb, int rate)
492
{
493
  return scb->ops->setbaudrate (scb, rate);
494
}
495
 
496
int
497
serial_setstopbits (struct serial *scb, int num)
498
{
499
  return scb->ops->setstopbits (scb, num);
500
}
501
 
502
int
503
serial_can_async_p (struct serial *scb)
504
{
505
  return (scb->ops->async != NULL);
506
}
507
 
508
int
509
serial_is_async_p (struct serial *scb)
510
{
511
  return (scb->ops->async != NULL) && (scb->async_handler != NULL);
512
}
513
 
514
void
515
serial_async (struct serial *scb,
516
              serial_event_ftype *handler,
517
              void *context)
518
{
519
  int changed = ((scb->async_handler == NULL) != (handler == NULL));
520
  scb->async_handler = handler;
521
  scb->async_context = context;
522
  /* Only change mode if there is a need.  */
523
  if (changed)
524
    scb->ops->async (scb, handler != NULL);
525
}
526
 
527
int
528
deprecated_serial_fd (struct serial *scb)
529
{
530
  /* FIXME: should this output a warning that deprecated code is being
531
     called? */
532
  if (scb->fd < 0)
533
    {
534
      internal_error (__FILE__, __LINE__,
535
                      _("serial: FD not valid"));
536
    }
537
  return scb->fd; /* sigh */
538
}
539
 
540
void
541
serial_debug (struct serial *scb, int debug_p)
542
{
543
  scb->debug_p = debug_p;
544
}
545
 
546
int
547
serial_debug_p (struct serial *scb)
548
{
549
  return scb->debug_p || global_serial_debug_p;
550
}
551
 
552
#ifdef USE_WIN32API
553
void
554
serial_wait_handle (struct serial *scb, HANDLE *read, HANDLE *except)
555
{
556
  if (scb->ops->wait_handle)
557
    scb->ops->wait_handle (scb, read, except);
558
  else
559
    {
560
      *read = (HANDLE) _get_osfhandle (scb->fd);
561
      *except = NULL;
562
    }
563
}
564
 
565
void
566
serial_done_wait_handle (struct serial *scb)
567
{
568
  if (scb->ops->done_wait_handle)
569
    scb->ops->done_wait_handle (scb);
570
}
571
#endif
572
 
573
#if 0
574
/* The connect command is #if 0 because I hadn't thought of an elegant
575
   way to wait for I/O on two `struct serial *'s simultaneously.  Two
576
   solutions came to mind:
577
 
578
   1) Fork, and have have one fork handle the to user direction,
579
   and have the other hand the to target direction.  This
580
   obviously won't cut it for MSDOS.
581
 
582
   2) Use something like select.  This assumes that stdin and
583
   the target side can both be waited on via the same
584
   mechanism.  This may not be true for DOS, if GDB is
585
   talking to the target via a TCP socket.
586
   -grossman, 8 Jun 93 */
587
 
588
/* Connect the user directly to the remote system.  This command acts just like
589
   the 'cu' or 'tip' command.  Use <CR>~. or <CR>~^D to break out.  */
590
 
591
static struct serial *tty_desc; /* Controlling terminal */
592
 
593
static void
594
cleanup_tty (serial_ttystate ttystate)
595
{
596
  printf_unfiltered ("\r\n[Exiting connect mode]\r\n");
597
  serial_set_tty_state (tty_desc, ttystate);
598
  xfree (ttystate);
599
  serial_close (tty_desc);
600
}
601
 
602
static void
603
connect_command (char *args, int fromtty)
604
{
605
  int c;
606
  char cur_esc = 0;
607
  serial_ttystate ttystate;
608
  struct serial *port_desc;             /* TTY port */
609
 
610
  dont_repeat ();
611
 
612
  if (args)
613
    fprintf_unfiltered (gdb_stderr, "This command takes no args.  They have been ignored.\n");
614
 
615
  printf_unfiltered ("[Entering connect mode.  Use ~. or ~^D to escape]\n");
616
 
617
  tty_desc = serial_fdopen (0);
618
  port_desc = last_serial_opened;
619
 
620
  ttystate = serial_get_tty_state (tty_desc);
621
 
622
  serial_raw (tty_desc);
623
  serial_raw (port_desc);
624
 
625
  make_cleanup (cleanup_tty, ttystate);
626
 
627
  while (1)
628
    {
629
      int mask;
630
 
631
      mask = serial_wait_2 (tty_desc, port_desc, -1);
632
 
633
      if (mask & 2)
634
        {                       /* tty input */
635
          char cx;
636
 
637
          while (1)
638
            {
639
              c = serial_readchar (tty_desc, 0);
640
 
641
              if (c == SERIAL_TIMEOUT)
642
                break;
643
 
644
              if (c < 0)
645
                perror_with_name (_("connect"));
646
 
647
              cx = c;
648
              serial_write (port_desc, &cx, 1);
649
 
650
              switch (cur_esc)
651
                {
652
                case 0:
653
                  if (c == '\r')
654
                    cur_esc = c;
655
                  break;
656
                case '\r':
657
                  if (c == '~')
658
                    cur_esc = c;
659
                  else
660
                    cur_esc = 0;
661
                  break;
662
                case '~':
663
                  if (c == '.' || c == '\004')
664
                    return;
665
                  else
666
                    cur_esc = 0;
667
                }
668
            }
669
        }
670
 
671
      if (mask & 1)
672
        {                       /* Port input */
673
          char cx;
674
 
675
          while (1)
676
            {
677
              c = serial_readchar (port_desc, 0);
678
 
679
              if (c == SERIAL_TIMEOUT)
680
                break;
681
 
682
              if (c < 0)
683
                perror_with_name (_("connect"));
684
 
685
              cx = c;
686
 
687
              serial_write (tty_desc, &cx, 1);
688
            }
689
        }
690
    }
691
}
692
#endif /* 0 */
693
 
694
/* Serial set/show framework.  */
695
 
696
static struct cmd_list_element *serial_set_cmdlist;
697
static struct cmd_list_element *serial_show_cmdlist;
698
 
699
static void
700
serial_set_cmd (char *args, int from_tty)
701
{
702
  printf_unfiltered ("\"set serial\" must be followed by the name of a command.\n");
703
  help_list (serial_set_cmdlist, "set serial ", -1, gdb_stdout);
704
}
705
 
706
static void
707
serial_show_cmd (char *args, int from_tty)
708
{
709
  cmd_show_list (serial_show_cmdlist, from_tty, "");
710
}
711
 
712
 
713
void
714
_initialize_serial (void)
715
{
716
#if 0
717
  add_com ("connect", class_obscure, connect_command, _("\
718
Connect the terminal directly up to the command monitor.\n\
719
Use <CR>~. or <CR>~^D to break out."));
720
#endif /* 0 */
721
 
722
  add_prefix_cmd ("serial", class_maintenance, serial_set_cmd, _("\
723
Set default serial/parallel port configuration."),
724
                  &serial_set_cmdlist, "set serial ",
725
                  0/*allow-unknown*/,
726
                  &setlist);
727
 
728
  add_prefix_cmd ("serial", class_maintenance, serial_show_cmd, _("\
729
Show default serial/parallel port configuration."),
730
                  &serial_show_cmdlist, "show serial ",
731
                  0/*allow-unknown*/,
732
                  &showlist);
733
 
734
  add_setshow_filename_cmd ("remotelogfile", no_class, &serial_logfile, _("\
735
Set filename for remote session recording."), _("\
736
Show filename for remote session recording."), _("\
737
This file is used to record the remote session for future playback\n\
738
by gdbserver."),
739
                            NULL,
740
                            NULL, /* FIXME: i18n: */
741
                            &setlist, &showlist);
742
 
743
  add_setshow_enum_cmd ("remotelogbase", no_class, logbase_enums,
744
                        &serial_logbase, _("\
745
Set numerical base for remote session logging"), _("\
746
Show numerical base for remote session logging"), NULL,
747
                        NULL,
748
                        NULL, /* FIXME: i18n: */
749
                        &setlist, &showlist);
750
 
751
  add_setshow_zinteger_cmd ("serial", class_maintenance,
752
                            &global_serial_debug_p, _("\
753
Set serial debugging."), _("\
754
Show serial debugging."), _("\
755
When non-zero, serial port debugging is enabled."),
756
                            NULL,
757
                            NULL, /* FIXME: i18n: */
758
                            &setdebuglist, &showdebuglist);
759
}

powered by: WebSVN 2.1.0

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