OSDN Git Service

Copyright updates for 2007.
[pf3gnuchains/sourceware.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    2007 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 }