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