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