]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/ser-tcp.c
import gdb-1999-09-08 snapshot
[thirdparty/binutils-gdb.git] / gdb / ser-tcp.c
CommitLineData
c906108c 1/* Serial interface for raw TCP connections on Un*x like systems
9846de1b 2 Copyright 1992, 1993, 1998 Free Software Foundation, Inc.
c906108c 3
c5aa993b 4 This file is part of GDB.
c906108c 5
c5aa993b
JM
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.
c906108c 10
c5aa993b
JM
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.
c906108c 15
c5aa993b
JM
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., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
c906108c
SS
20
21#include "defs.h"
22#include "serial.h"
23#include <sys/types.h>
24#include <sys/time.h>
25#include <netinet/in.h>
26#include <arpa/inet.h>
27#include <netdb.h>
28#include <sys/socket.h>
29
30#ifndef __CYGWIN32__
31#include <netinet/tcp.h>
32#endif
33
34#include "signals.h"
35#include "gdb_string.h"
36
7a292a7a
SS
37extern int (*ui_loop_hook) PARAMS ((int));
38
c906108c 39struct tcp_ttystate
c5aa993b
JM
40 {
41 int bogus;
42 };
c906108c
SS
43
44static int tcp_open PARAMS ((serial_t scb, const char *name));
45static void tcp_raw PARAMS ((serial_t scb));
46static int wait_for PARAMS ((serial_t scb, int timeout));
47static int tcp_readchar PARAMS ((serial_t scb, int timeout));
48static int tcp_setbaudrate PARAMS ((serial_t scb, int rate));
49static int tcp_setstopbits PARAMS ((serial_t scb, int num));
50static int tcp_write PARAMS ((serial_t scb, const char *str, int len));
51/* FIXME: static void tcp_restore PARAMS ((serial_t scb)); */
52static void tcp_close PARAMS ((serial_t scb));
53static serial_ttystate tcp_get_tty_state PARAMS ((serial_t scb));
54static int tcp_set_tty_state PARAMS ((serial_t scb, serial_ttystate state));
55static int tcp_return_0 PARAMS ((serial_t));
56static int tcp_noflush_set_tty_state PARAMS ((serial_t, serial_ttystate,
57 serial_ttystate));
58static void tcp_print_tty_state PARAMS ((serial_t, serial_ttystate));
59
60void _initialize_ser_tcp PARAMS ((void));
61
62/* Open up a raw tcp socket */
63
64static int
c5aa993b 65tcp_open (scb, name)
c906108c
SS
66 serial_t scb;
67 const char *name;
68{
69 char *port_str;
70 int port;
71 struct hostent *hostent;
72 struct sockaddr_in sockaddr;
73 int tmp;
74 char hostname[100];
75 struct protoent *protoent;
76 int i;
77
78 port_str = strchr (name, ':');
79
80 if (!port_str)
c5aa993b 81 error ("tcp_open: No colon in host name!"); /* Shouldn't ever happen */
c906108c
SS
82
83 tmp = min (port_str - name, (int) sizeof hostname - 1);
c5aa993b 84 strncpy (hostname, name, tmp); /* Don't want colon */
c906108c
SS
85 hostname[tmp] = '\000'; /* Tie off host name */
86 port = atoi (port_str + 1);
87
88 hostent = gethostbyname (hostname);
89
90 if (!hostent)
91 {
92 fprintf_unfiltered (gdb_stderr, "%s: unknown host\n", hostname);
93 errno = ENOENT;
94 return -1;
95 }
96
97 for (i = 1; i <= 15; i++)
98 {
99 scb->fd = socket (PF_INET, SOCK_STREAM, 0);
100 if (scb->fd < 0)
101 return -1;
102
103 /* Allow rapid reuse of this port. */
104 tmp = 1;
c5aa993b 105 setsockopt (scb->fd, SOL_SOCKET, SO_REUSEADDR, (char *) &tmp, sizeof (tmp));
c906108c
SS
106
107 /* Enable TCP keep alive process. */
108 tmp = 1;
c5aa993b 109 setsockopt (scb->fd, SOL_SOCKET, SO_KEEPALIVE, (char *) &tmp, sizeof (tmp));
c906108c
SS
110
111 sockaddr.sin_family = PF_INET;
c5aa993b 112 sockaddr.sin_port = htons (port);
c906108c
SS
113 memcpy (&sockaddr.sin_addr.s_addr, hostent->h_addr,
114 sizeof (struct in_addr));
115
c5aa993b 116 if (!connect (scb->fd, (struct sockaddr *) &sockaddr, sizeof (sockaddr)))
c906108c
SS
117 break;
118
119 close (scb->fd);
120 scb->fd = -1;
121
122/* We retry for ECONNREFUSED because that is often a temporary condition, which
123 happens when the server is being restarted. */
124
125 if (errno != ECONNREFUSED)
126 return -1;
127
128 sleep (1);
129 }
130
131 protoent = getprotobyname ("tcp");
132 if (!protoent)
133 return -1;
134
135 tmp = 1;
136 if (setsockopt (scb->fd, protoent->p_proto, TCP_NODELAY,
c5aa993b 137 (char *) &tmp, sizeof (tmp)))
c906108c
SS
138 return -1;
139
c5aa993b 140 signal (SIGPIPE, SIG_IGN); /* If we don't do this, then GDB simply exits
c906108c
SS
141 when the remote side dies. */
142
143 return 0;
144}
145
146static serial_ttystate
c5aa993b 147tcp_get_tty_state (scb)
c906108c
SS
148 serial_t scb;
149{
150 struct tcp_ttystate *state;
151
c5aa993b 152 state = (struct tcp_ttystate *) xmalloc (sizeof *state);
c906108c 153
c5aa993b 154 return (serial_ttystate) state;
c906108c
SS
155}
156
157static int
c5aa993b 158tcp_set_tty_state (scb, ttystate)
c906108c
SS
159 serial_t scb;
160 serial_ttystate ttystate;
161{
162 struct tcp_ttystate *state;
163
c5aa993b 164 state = (struct tcp_ttystate *) ttystate;
c906108c
SS
165
166 return 0;
167}
168
169static int
170tcp_return_0 (scb)
171 serial_t scb;
172{
173 return 0;
174}
175
176static void
c5aa993b 177tcp_raw (scb)
c906108c
SS
178 serial_t scb;
179{
180 return; /* Always in raw mode */
181}
182
183/* Wait for input on scb, with timeout seconds. Returns 0 on success,
184 otherwise SERIAL_TIMEOUT or SERIAL_ERROR.
185
186 For termio{s}, we actually just setup VTIME if necessary, and let the
187 timeout occur in the read() in tcp_read().
188 */
189
190static int
191wait_for (scb, timeout)
192 serial_t scb;
193 int timeout;
194{
195 int numfds;
196 struct timeval tv;
197 fd_set readfds, exceptfds;
198
199 FD_ZERO (&readfds);
200 FD_ZERO (&exceptfds);
201
202 tv.tv_sec = timeout;
203 tv.tv_usec = 0;
204
c5aa993b
JM
205 FD_SET (scb->fd, &readfds);
206 FD_SET (scb->fd, &exceptfds);
c906108c
SS
207
208 while (1)
209 {
210 if (timeout >= 0)
c5aa993b 211 numfds = select (scb->fd + 1, &readfds, 0, &exceptfds, &tv);
c906108c 212 else
c5aa993b 213 numfds = select (scb->fd + 1, &readfds, 0, &exceptfds, 0);
c906108c
SS
214
215 if (numfds <= 0)
c5aa993b 216 {
c906108c
SS
217 if (numfds == 0)
218 return SERIAL_TIMEOUT;
219 else if (errno == EINTR)
220 continue;
221 else
222 return SERIAL_ERROR; /* Got an error from select or poll */
c5aa993b 223 }
c906108c
SS
224
225 return 0;
226 }
227}
228
229/* Read a character with user-specified timeout. TIMEOUT is number of seconds
230 to wait, or -1 to wait forever. Use timeout of 0 to effect a poll. Returns
231 char if successful. Returns -2 if timeout expired, EOF if line dropped
232 dead, or -3 for any other error (see errno in that case). */
233
234static int
235tcp_readchar (scb, timeout)
236 serial_t scb;
237 int timeout;
238{
239 int status;
7a292a7a 240 int delta;
c906108c
SS
241
242 if (scb->bufcnt-- > 0)
243 return *scb->bufp++;
244
7a292a7a
SS
245 /* We have to be able to keep the GUI alive here, so we break the original
246 timeout into steps of 1 second, running the "keep the GUI alive" hook
247 each time through the loop.
248
249 Also, timeout = 0 means to poll, so we just set the delta to 0, so we
250 will only go through the loop once. */
c5aa993b 251
7a292a7a
SS
252 delta = (timeout == 0 ? 0 : 1);
253 while (1)
254 {
255
256 /* N.B. The UI may destroy our world (for instance by calling
c5aa993b
JM
257 remote_stop,) in which case we want to get out of here as
258 quickly as possible. It is not safe to touch scb, since
259 someone else might have freed it. The ui_loop_hook signals that
260 we should exit by returning 1. */
7a292a7a
SS
261
262 if (ui_loop_hook)
263 {
264 if (ui_loop_hook (0))
265 return SERIAL_TIMEOUT;
266 }
267
268 status = wait_for (scb, delta);
269 timeout -= delta;
270
271 /* If we got a character or an error back from wait_for, then we can
272 break from the loop before the timeout is completed. */
c5aa993b 273
7a292a7a
SS
274 if (status != SERIAL_TIMEOUT)
275 {
276 break;
277 }
278
279 /* If we have exhausted the original timeout, then generate
c5aa993b
JM
280 a SERIAL_TIMEOUT, and pass it out of the loop. */
281
7a292a7a
SS
282 else if (timeout == 0)
283 {
d4f3574e 284 status = SERIAL_TIMEOUT;
7a292a7a
SS
285 break;
286 }
287 }
c906108c
SS
288
289 if (status < 0)
290 return status;
291
292 while (1)
293 {
c5aa993b 294 scb->bufcnt = read (scb->fd, scb->buf, BUFSIZ);
c906108c
SS
295 if (scb->bufcnt != -1 || errno != EINTR)
296 break;
297 }
298
299 if (scb->bufcnt <= 0)
300 {
301 if (scb->bufcnt == 0)
c5aa993b
JM
302 return SERIAL_TIMEOUT; /* 0 chars means timeout [may need to
303 distinguish between EOF & timeouts
304 someday] */
c906108c 305 else
c5aa993b 306 return SERIAL_ERROR; /* Got an error from read */
c906108c
SS
307 }
308
309 scb->bufcnt--;
310 scb->bufp = scb->buf;
311 return *scb->bufp++;
312}
313
314static int
315tcp_noflush_set_tty_state (scb, new_ttystate, old_ttystate)
316 serial_t scb;
317 serial_ttystate new_ttystate;
318 serial_ttystate old_ttystate;
319{
320 return 0;
321}
322
323static void
324tcp_print_tty_state (scb, ttystate)
325 serial_t scb;
326 serial_ttystate ttystate;
327{
328 /* Nothing to print. */
329 return;
330}
331
332static int
c5aa993b 333tcp_setbaudrate (scb, rate)
c906108c
SS
334 serial_t scb;
335 int rate;
336{
337 return 0; /* Never fails! */
338}
339
340static int
c5aa993b 341tcp_setstopbits (scb, num)
c906108c
SS
342 serial_t scb;
343 int num;
344{
345 return 0; /* Never fails! */
346}
347
348static int
c5aa993b 349tcp_write (scb, str, len)
c906108c
SS
350 serial_t scb;
351 const char *str;
352 int len;
353{
354 int cc;
355
356 while (len > 0)
357 {
c5aa993b 358 cc = write (scb->fd, str, len);
c906108c
SS
359
360 if (cc < 0)
361 return 1;
362 len -= cc;
363 str += cc;
364 }
365 return 0;
366}
367
368static void
c5aa993b 369tcp_close (scb)
c906108c
SS
370 serial_t scb;
371{
372 if (scb->fd < 0)
373 return;
374
c5aa993b 375 close (scb->fd);
c906108c
SS
376 scb->fd = -1;
377}
378
379static struct serial_ops tcp_ops =
380{
381 "tcp",
382 0,
383 tcp_open,
384 tcp_close,
385 tcp_readchar,
386 tcp_write,
c5aa993b
JM
387 tcp_return_0, /* flush output */
388 tcp_return_0, /* flush input */
389 tcp_return_0, /* send break */
c906108c
SS
390 tcp_raw,
391 tcp_get_tty_state,
392 tcp_set_tty_state,
393 tcp_print_tty_state,
394 tcp_noflush_set_tty_state,
395 tcp_setbaudrate,
396 tcp_setstopbits,
c5aa993b 397 tcp_return_0, /* wait for output to drain */
c906108c
SS
398};
399
400void
401_initialize_ser_tcp ()
402{
403 serial_add_interface (&tcp_ops);
404}