]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/ser-tcp.c
Copyright updates for 2007.
[thirdparty/binutils-gdb.git] / gdb / ser-tcp.c
CommitLineData
f9f87d2c
MK
1/* Serial interface for raw TCP connections on Un*x like systems.
2
6aba47ca
DJ
3 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2001, 2005, 2006,
4 2007 Free Software Foundation, Inc.
c906108c 5
c5aa993b 6 This file is part of GDB.
c906108c 7
c5aa993b
JM
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
c906108c 12
c5aa993b
JM
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
c906108c 17
c5aa993b
JM
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
197e01b6
EZ
20 Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA. */
c906108c
SS
22
23#include "defs.h"
24#include "serial.h"
3eb25fda 25#include "ser-base.h"
0ea3f30e 26#include "ser-tcp.h"
c2c6d25f 27
c906108c 28#include <sys/types.h>
0cf3e697
MH
29
30#ifdef HAVE_SYS_FILIO_H
31#include <sys/filio.h> /* For FIONBIO. */
32#endif
33#ifdef HAVE_SYS_IOCTL_H
34#include <sys/ioctl.h> /* For FIONBIO. */
35#endif
36
c906108c 37#include <sys/time.h>
b4505029
MM
38
39#ifdef USE_WIN32API
40#include <winsock2.h>
41#define ETIMEDOUT WSAETIMEDOUT
056d7646 42#define close(fd) closesocket (fd)
b4505029
MM
43#define ioctl ioctlsocket
44#else
c906108c
SS
45#include <netinet/in.h>
46#include <arpa/inet.h>
47#include <netdb.h>
48#include <sys/socket.h>
c906108c 49#include <netinet/tcp.h>
b4505029 50#endif
c906108c 51
042be3a9 52#include <signal.h>
c906108c
SS
53#include "gdb_string.h"
54
f9f87d2c
MK
55#ifndef HAVE_SOCKLEN_T
56typedef int socklen_t;
57#endif
58
c2c6d25f 59void _initialize_ser_tcp (void);
c906108c 60
7c7a201a
MH
61/* seconds to wait for connect */
62#define TIMEOUT 15
98bbd631 63/* how many times per second to poll deprecated_ui_loop_hook */
7c7a201a
MH
64#define POLL_INTERVAL 2
65
66/* Open a tcp socket */
c906108c 67
0ea3f30e 68int
9db8d71f 69net_open (struct serial *scb, const char *name)
c906108c 70{
7c7a201a
MH
71 char *port_str, hostname[100];
72 int n, port, tmp;
9db8d71f 73 int use_udp;
c906108c
SS
74 struct hostent *hostent;
75 struct sockaddr_in sockaddr;
b4505029
MM
76#ifdef USE_WIN32API
77 u_long ioarg;
78#else
79 int ioarg;
80#endif
c906108c 81
9db8d71f
DJ
82 use_udp = 0;
83 if (strncmp (name, "udp:", 4) == 0)
84 {
85 use_udp = 1;
86 name = name + 4;
87 }
88 else if (strncmp (name, "tcp:", 4) == 0)
89 name = name + 4;
90
c906108c
SS
91 port_str = strchr (name, ':');
92
93 if (!port_str)
8a3fe4f8 94 error (_("net_open: No colon in host name!")); /* Shouldn't ever happen */
c906108c
SS
95
96 tmp = min (port_str - name, (int) sizeof hostname - 1);
c5aa993b 97 strncpy (hostname, name, tmp); /* Don't want colon */
c906108c
SS
98 hostname[tmp] = '\000'; /* Tie off host name */
99 port = atoi (port_str + 1);
100
7c7a201a 101 /* default hostname is localhost */
ad4571f3
CV
102 if (!hostname[0])
103 strcpy (hostname, "localhost");
104
c906108c 105 hostent = gethostbyname (hostname);
c906108c
SS
106 if (!hostent)
107 {
108 fprintf_unfiltered (gdb_stderr, "%s: unknown host\n", hostname);
109 errno = ENOENT;
110 return -1;
111 }
112
9db8d71f
DJ
113 if (use_udp)
114 scb->fd = socket (PF_INET, SOCK_DGRAM, 0);
115 else
116 scb->fd = socket (PF_INET, SOCK_STREAM, 0);
117
7c7a201a
MH
118 if (scb->fd < 0)
119 return -1;
120
121 sockaddr.sin_family = PF_INET;
122 sockaddr.sin_port = htons (port);
123 memcpy (&sockaddr.sin_addr.s_addr, hostent->h_addr,
124 sizeof (struct in_addr));
c906108c 125
7c7a201a 126 /* set socket nonblocking */
b4505029
MM
127 ioarg = 1;
128 ioctl (scb->fd, FIONBIO, &ioarg);
c906108c 129
7c7a201a
MH
130 /* Use Non-blocking connect. connect() will return 0 if connected already. */
131 n = connect (scb->fd, (struct sockaddr *) &sockaddr, sizeof (sockaddr));
c906108c 132
b4505029
MM
133 if (n < 0
134#ifdef USE_WIN32API
135 /* Under Windows, calling "connect" with a non-blocking socket
136 results in WSAEWOULDBLOCK, not WSAEINPROGRESS. */
137 && WSAGetLastError() != WSAEWOULDBLOCK
138#else
139 && errno != EINPROGRESS
140#endif
141 )
7c7a201a 142 {
b4505029
MM
143#ifdef USE_WIN32API
144 errno = WSAGetLastError();
145#endif
9db8d71f 146 net_close (scb);
7c7a201a 147 return -1;
c906108c
SS
148 }
149
7c7a201a
MH
150 if (n)
151 {
152 /* looks like we need to wait for the connect */
153 struct timeval t;
0ea3f30e 154 fd_set rset, wset, eset;
7c7a201a
MH
155 int polls = 0;
156 FD_ZERO (&rset);
157
158 do
159 {
2c1ab592 160 /* While we wait for the connect to complete,
7c7a201a 161 poll the UI so it can update or the user can
2c1ab592 162 interrupt. */
98bbd631 163 if (deprecated_ui_loop_hook)
7c7a201a 164 {
98bbd631 165 if (deprecated_ui_loop_hook (0))
7c7a201a
MH
166 {
167 errno = EINTR;
9db8d71f 168 net_close (scb);
7c7a201a
MH
169 return -1;
170 }
171 }
172
173 FD_SET (scb->fd, &rset);
174 wset = rset;
0ea3f30e 175 eset = rset;
7c7a201a
MH
176 t.tv_sec = 0;
177 t.tv_usec = 1000000 / POLL_INTERVAL;
178
0ea3f30e
DJ
179 /* POSIX systems return connection success or failure by signalling
180 wset. Windows systems return success in wset and failure in
181 eset.
182
183 We must call select here, rather than gdb_select, because
184 the serial structure has not yet been initialized - the
185 MinGW select wrapper will not know that this FD refers
186 to a socket. */
187 n = select (scb->fd + 1, &rset, &wset, &eset, &t);
7c7a201a
MH
188 polls++;
189 }
190 while (n == 0 && polls <= TIMEOUT * POLL_INTERVAL);
191 if (n < 0 || polls > TIMEOUT * POLL_INTERVAL)
192 {
193 if (polls > TIMEOUT * POLL_INTERVAL)
194 errno = ETIMEDOUT;
9db8d71f 195 net_close (scb);
7c7a201a
MH
196 return -1;
197 }
198 }
c906108c 199
7c7a201a
MH
200 /* Got something. Is it an error? */
201 {
47b667de
AC
202 int res, err;
203 socklen_t len;
0ea3f30e 204 len = sizeof (err);
b4505029
MM
205 /* On Windows, the fourth parameter to getsockopt is a "char *";
206 on UNIX systems it is generally "void *". The cast to "void *"
207 is OK everywhere, since in C "void *" can be implicitly
208 converted to any pointer type. */
209 res = getsockopt (scb->fd, SOL_SOCKET, SO_ERROR, (void *) &err, &len);
7c7a201a
MH
210 if (res < 0 || err)
211 {
212 if (err)
213 errno = err;
9db8d71f 214 net_close (scb);
7c7a201a
MH
215 return -1;
216 }
217 }
9db8d71f 218
7c7a201a 219 /* turn off nonblocking */
b4505029
MM
220 ioarg = 0;
221 ioctl (scb->fd, FIONBIO, &ioarg);
7c7a201a 222
9db8d71f
DJ
223 if (use_udp == 0)
224 {
225 /* Disable Nagle algorithm. Needed in some cases. */
226 tmp = 1;
227 setsockopt (scb->fd, IPPROTO_TCP, TCP_NODELAY,
228 (char *)&tmp, sizeof (tmp));
229 }
230
6d318c73 231#ifdef SIGPIPE
7c7a201a
MH
232 /* If we don't do this, then GDB simply exits
233 when the remote side dies. */
234 signal (SIGPIPE, SIG_IGN);
6d318c73 235#endif
c906108c
SS
236
237 return 0;
238}
239
0ea3f30e 240void
9db8d71f 241net_close (struct serial *scb)
c906108c
SS
242{
243 if (scb->fd < 0)
244 return;
245
c5aa993b 246 close (scb->fd);
c906108c
SS
247 scb->fd = -1;
248}
249
0ea3f30e 250int
b4505029
MM
251net_read_prim (struct serial *scb, size_t count)
252{
253 return recv (scb->fd, scb->buf, count, 0);
254}
255
0ea3f30e 256int
b4505029
MM
257net_write_prim (struct serial *scb, const void *buf, size_t count)
258{
259 return send (scb->fd, buf, count, 0);
260}
261
c906108c 262void
c2c6d25f 263_initialize_ser_tcp (void)
c906108c 264{
b4505029 265#ifdef USE_WIN32API
0ea3f30e
DJ
266 /* Do nothing; the TCP serial operations will be initialized in
267 ser-mingw.c. */
268 return;
269#else
270 struct serial_ops *ops;
b4505029 271 ops = XMALLOC (struct serial_ops);
2fdbdd39 272 memset (ops, 0, sizeof (struct serial_ops));
c2c6d25f
JM
273 ops->name = "tcp";
274 ops->next = 0;
9db8d71f
DJ
275 ops->open = net_open;
276 ops->close = net_close;
b4505029 277 ops->readchar = ser_base_readchar;
dd5da072
MM
278 ops->write = ser_base_write;
279 ops->flush_output = ser_base_flush_output;
280 ops->flush_input = ser_base_flush_input;
281 ops->send_break = ser_base_send_break;
282 ops->go_raw = ser_base_raw;
283 ops->get_tty_state = ser_base_get_tty_state;
284 ops->set_tty_state = ser_base_set_tty_state;
285 ops->print_tty_state = ser_base_print_tty_state;
286 ops->noflush_set_tty_state = ser_base_noflush_set_tty_state;
287 ops->setbaudrate = ser_base_setbaudrate;
288 ops->setstopbits = ser_base_setstopbits;
289 ops->drain_output = ser_base_drain_output;
290 ops->async = ser_base_async;
b4505029
MM
291 ops->read_prim = net_read_prim;
292 ops->write_prim = net_write_prim;
c2c6d25f 293 serial_add_interface (ops);
0ea3f30e 294#endif /* USE_WIN32API */
c906108c 295}