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