]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/ser-tcp.c
bd104aa8f1e25d5c499807c6a48949f7a3f9fa11
[thirdparty/binutils-gdb.git] / gdb / ser-tcp.c
1 /* Serial interface for raw TCP connections on Un*x like systems.
2
3 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2001, 2005, 2006
4 Free Software Foundation, Inc.
5
6 This file is part of GDB.
7
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.
12
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.
17
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
20 Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA. */
22
23 #include "defs.h"
24 #include "serial.h"
25 #include "ser-base.h"
26 #include "ser-tcp.h"
27
28 #include <sys/types.h>
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
37 #include <sys/time.h>
38
39 #ifdef USE_WIN32API
40 #include <winsock2.h>
41 #define ETIMEDOUT WSAETIMEDOUT
42 #define close(fd) closesocket (fd)
43 #define ioctl ioctlsocket
44 #else
45 #include <netinet/in.h>
46 #include <arpa/inet.h>
47 #include <netdb.h>
48 #include <sys/socket.h>
49 #include <netinet/tcp.h>
50 #endif
51
52 #include <signal.h>
53 #include "gdb_string.h"
54
55 #ifndef HAVE_SOCKLEN_T
56 typedef int socklen_t;
57 #endif
58
59 void _initialize_ser_tcp (void);
60
61 /* seconds to wait for connect */
62 #define TIMEOUT 15
63 /* how many times per second to poll deprecated_ui_loop_hook */
64 #define POLL_INTERVAL 2
65
66 /* Open a tcp socket */
67
68 int
69 net_open (struct serial *scb, const char *name)
70 {
71 char *port_str, hostname[100];
72 int n, port, tmp;
73 int use_udp;
74 struct hostent *hostent;
75 struct sockaddr_in sockaddr;
76 #ifdef USE_WIN32API
77 u_long ioarg;
78 #else
79 int ioarg;
80 #endif
81
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
91 port_str = strchr (name, ':');
92
93 if (!port_str)
94 error (_("net_open: No colon in host name!")); /* Shouldn't ever happen */
95
96 tmp = min (port_str - name, (int) sizeof hostname - 1);
97 strncpy (hostname, name, tmp); /* Don't want colon */
98 hostname[tmp] = '\000'; /* Tie off host name */
99 port = atoi (port_str + 1);
100
101 /* default hostname is localhost */
102 if (!hostname[0])
103 strcpy (hostname, "localhost");
104
105 hostent = gethostbyname (hostname);
106 if (!hostent)
107 {
108 fprintf_unfiltered (gdb_stderr, "%s: unknown host\n", hostname);
109 errno = ENOENT;
110 return -1;
111 }
112
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
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));
125
126 /* set socket nonblocking */
127 ioarg = 1;
128 ioctl (scb->fd, FIONBIO, &ioarg);
129
130 /* Use Non-blocking connect. connect() will return 0 if connected already. */
131 n = connect (scb->fd, (struct sockaddr *) &sockaddr, sizeof (sockaddr));
132
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 )
142 {
143 #ifdef USE_WIN32API
144 errno = WSAGetLastError();
145 #endif
146 net_close (scb);
147 return -1;
148 }
149
150 if (n)
151 {
152 /* looks like we need to wait for the connect */
153 struct timeval t;
154 fd_set rset, wset, eset;
155 int polls = 0;
156 FD_ZERO (&rset);
157
158 do
159 {
160 /* While we wait for the connect to complete,
161 poll the UI so it can update or the user can
162 interrupt. */
163 if (deprecated_ui_loop_hook)
164 {
165 if (deprecated_ui_loop_hook (0))
166 {
167 errno = EINTR;
168 net_close (scb);
169 return -1;
170 }
171 }
172
173 FD_SET (scb->fd, &rset);
174 wset = rset;
175 eset = rset;
176 t.tv_sec = 0;
177 t.tv_usec = 1000000 / POLL_INTERVAL;
178
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);
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;
195 net_close (scb);
196 return -1;
197 }
198 }
199
200 /* Got something. Is it an error? */
201 {
202 int res, err;
203 socklen_t len;
204 len = sizeof (err);
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);
210 if (res < 0 || err)
211 {
212 if (err)
213 errno = err;
214 net_close (scb);
215 return -1;
216 }
217 }
218
219 /* turn off nonblocking */
220 ioarg = 0;
221 ioctl (scb->fd, FIONBIO, &ioarg);
222
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
231 #ifdef SIGPIPE
232 /* If we don't do this, then GDB simply exits
233 when the remote side dies. */
234 signal (SIGPIPE, SIG_IGN);
235 #endif
236
237 return 0;
238 }
239
240 void
241 net_close (struct serial *scb)
242 {
243 if (scb->fd < 0)
244 return;
245
246 close (scb->fd);
247 scb->fd = -1;
248 }
249
250 int
251 net_read_prim (struct serial *scb, size_t count)
252 {
253 return recv (scb->fd, scb->buf, count, 0);
254 }
255
256 int
257 net_write_prim (struct serial *scb, const void *buf, size_t count)
258 {
259 return send (scb->fd, buf, count, 0);
260 }
261
262 void
263 _initialize_ser_tcp (void)
264 {
265 #ifdef USE_WIN32API
266 /* Do nothing; the TCP serial operations will be initialized in
267 ser-mingw.c. */
268 return;
269 #else
270 struct serial_ops *ops;
271 ops = XMALLOC (struct serial_ops);
272 memset (ops, 0, sizeof (struct serial_ops));
273 ops->name = "tcp";
274 ops->next = 0;
275 ops->open = net_open;
276 ops->close = net_close;
277 ops->readchar = ser_base_readchar;
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;
291 ops->read_prim = net_read_prim;
292 ops->write_prim = net_write_prim;
293 serial_add_interface (ops);
294 #endif /* USE_WIN32API */
295 }