]> Git Repo - binutils.git/blob - gdb/serial.c
* nlm/gdbserve.c: conditionalize header file inclusion for either
[binutils.git] / gdb / serial.c
1 /* Generic serial interface routines
2    Copyright 1992, 1993 Free Software Foundation, Inc.
3
4 This file is part of GDB.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
19
20 #include "defs.h"
21 #include "serial.h"
22
23 /* Linked list of serial I/O handlers */
24
25 static struct serial_ops *serial_ops_list = NULL;
26
27 /* This is the last serial stream opened.  Used by connect command. */
28
29 static serial_t last_serial_opened = NULL;
30
31 static struct serial_ops *
32 serial_interface_lookup (name)
33      char *name;
34 {
35   struct serial_ops *ops;
36
37   for (ops = serial_ops_list; ops; ops = ops->next)
38     if (strcmp (name, ops->name) == 0)
39       return ops;
40
41   return NULL;
42 }
43
44 void
45 serial_add_interface(optable)
46      struct serial_ops *optable;
47 {
48   optable->next = serial_ops_list;
49   serial_ops_list = optable;
50 }
51
52 /* Open up a device or a network socket, depending upon the syntax of NAME. */
53
54 serial_t
55 serial_open (name)
56      const char *name;
57 {
58   serial_t scb;
59   struct serial_ops *ops;
60
61   if (strcmp (name, "pc") == 0)
62     ops = serial_interface_lookup ("pc");
63   else if (strchr (name, ':'))
64     ops = serial_interface_lookup ("tcp");
65   else
66     ops = serial_interface_lookup ("hardwire");
67
68   if (!ops)
69     return NULL;
70
71   scb = (serial_t)xmalloc (sizeof (struct _serial_t));
72
73   scb->ops = ops;
74
75   scb->bufcnt = 0;
76   scb->bufp = scb->buf;
77
78   if (scb->ops->open(scb, name))
79     {
80       free (scb);
81       return NULL;
82     }
83
84   last_serial_opened = scb;
85
86   return scb;
87 }
88
89 serial_t
90 serial_fdopen(fd)
91      const int fd;
92 {
93   serial_t scb;
94   struct serial_ops *ops;
95
96   ops = serial_interface_lookup ("hardwire");
97
98   if (!ops)
99     return NULL;
100
101   scb = (serial_t)xmalloc (sizeof (struct _serial_t));
102
103   scb->ops = ops;
104
105   scb->bufcnt = 0;
106   scb->bufp = scb->buf;
107
108   scb->fd = fd;
109
110   last_serial_opened = scb;
111
112   return scb;
113 }
114
115 void
116 serial_close(scb)
117      serial_t scb;
118 {
119   last_serial_opened = NULL;
120
121 /* This is bogus.  It's not our fault if you pass us a bad scb...!  Rob, you
122    should fix your code instead.  */
123
124   if (!scb)
125     return;
126
127   scb->ops->close(scb);
128   free(scb);
129 }
130
131 #if 0
132 /*
133 The connect command is #if 0 because I hadn't thought of an elegant
134 way to wait for I/O on two serial_t's simultaneously.  Two solutions
135 came to mind:
136
137         1) Fork, and have have one fork handle the to user direction,
138            and have the other hand the to target direction.  This
139            obviously won't cut it for MSDOS.
140
141         2) Use something like select.  This assumes that stdin and
142            the target side can both be waited on via the same
143            mechanism.  This may not be true for DOS, if GDB is
144            talking to the target via a TCP socket.
145 -grossman, 8 Jun 93
146 */
147
148 /* Connect the user directly to the remote system.  This command acts just like
149    the 'cu' or 'tip' command.  Use <CR>~. or <CR>~^D to break out.  */
150
151 static serial_t tty_desc;               /* Controlling terminal */
152
153 static void
154 cleanup_tty(ttystate)
155      serial_ttystate ttystate;
156 {
157   printf_unfiltered ("\r\n[Exiting connect mode]\r\n");
158   SERIAL_SET_TTY_STATE (tty_desc, ttystate);
159   free (ttystate);
160   SERIAL_CLOSE (tty_desc);
161 }
162
163 static void
164 connect_command (args, fromtty)
165      char       *args;
166      int        fromtty;
167 {
168   int c;
169   char cur_esc = 0;
170   serial_ttystate ttystate;
171   serial_t port_desc;           /* TTY port */
172
173   dont_repeat();
174
175   if (args)
176     fprintf_unfiltered(gdb_stderr, "This command takes no args.  They have been ignored.\n");
177         
178   printf_unfiltered("[Entering connect mode.  Use ~. or ~^D to escape]\n");
179
180   tty_desc = SERIAL_FDOPEN (0);
181   port_desc = last_serial_opened;
182
183   ttystate = SERIAL_GET_TTY_STATE (tty_desc);
184
185   SERIAL_RAW (tty_desc);
186   SERIAL_RAW (port_desc);
187
188   make_cleanup (cleanup_tty, ttystate);
189
190   while (1)
191     {
192       int mask;
193
194       mask = SERIAL_WAIT_2 (tty_desc, port_desc, -1);
195
196       if (mask & 2)
197         {                       /* tty input */
198           char cx;
199
200           while (1)
201             {
202               c = SERIAL_READCHAR(tty_desc, 0);
203
204               if (c == SERIAL_TIMEOUT)
205                   break;
206
207               if (c < 0)
208                 perror_with_name("connect");
209
210               cx = c;
211               SERIAL_WRITE(port_desc, &cx, 1);
212
213               switch (cur_esc)
214                 {
215                 case 0:
216                   if (c == '\r')
217                     cur_esc = c;
218                   break;
219                 case '\r':
220                   if (c == '~')
221                     cur_esc = c;
222                   else
223                     cur_esc = 0;
224                   break;
225                 case '~':
226                   if (c == '.' || c == '\004')
227                     return;
228                   else
229                     cur_esc = 0;
230                 }
231             }
232         }
233
234       if (mask & 1)
235         {                       /* Port input */
236           char cx;
237
238           while (1)
239             {
240               c = SERIAL_READCHAR(port_desc, 0);
241
242               if (c == SERIAL_TIMEOUT)
243                   break;
244
245               if (c < 0)
246                 perror_with_name("connect");
247
248               cx = c;
249
250               SERIAL_WRITE(tty_desc, &cx, 1);
251             }
252         }
253     }
254 }
255 #endif /* 0 */
256
257 void
258 _initialize_serial ()
259 {
260 #if 0
261   add_com ("connect", class_obscure, connect_command,
262            "Connect the terminal directly up to the command monitor.\n\
263 Use <CR>~. or <CR>~^D to break out.");
264 #endif /* 0 */
265 }
This page took 0.039738 seconds and 4 git commands to generate.