xref: /dragonfly/contrib/gdb-7/gdb/ser-tcp.c (revision 6e278935)
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, 2008, 2009, 2010, 2011 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 3 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, see <http://www.gnu.org/licenses/>.  */
20 
21 #include "defs.h"
22 #include "serial.h"
23 #include "ser-base.h"
24 #include "ser-tcp.h"
25 #include "gdbcmd.h"
26 #include "cli/cli-decode.h"
27 #include "cli/cli-setshow.h"
28 
29 #include <sys/types.h>
30 
31 #ifdef HAVE_SYS_FILIO_H
32 #include <sys/filio.h>  /* For FIONBIO.  */
33 #endif
34 #ifdef HAVE_SYS_IOCTL_H
35 #include <sys/ioctl.h>  /* For FIONBIO.  */
36 #endif
37 
38 #include <sys/time.h>
39 
40 #ifdef USE_WIN32API
41 #include <winsock2.h>
42 #define ETIMEDOUT WSAETIMEDOUT
43 #define close(fd) closesocket (fd)
44 #define ioctl ioctlsocket
45 #else
46 #include <netinet/in.h>
47 #include <arpa/inet.h>
48 #include <netdb.h>
49 #include <sys/socket.h>
50 #include <netinet/tcp.h>
51 #endif
52 
53 #include <signal.h>
54 #include "gdb_string.h"
55 #include "gdb_select.h"
56 
57 #ifndef HAVE_SOCKLEN_T
58 typedef int socklen_t;
59 #endif
60 
61 void _initialize_ser_tcp (void);
62 
63 /* For "set tcp" and "show tcp".  */
64 
65 static struct cmd_list_element *tcp_set_cmdlist;
66 static struct cmd_list_element *tcp_show_cmdlist;
67 
68 /* Whether to auto-retry refused connections.  */
69 
70 static int tcp_auto_retry = 1;
71 
72 /* Timeout period for connections, in seconds.  */
73 
74 static int tcp_retry_limit = 15;
75 
76 /* How many times per second to poll deprecated_ui_loop_hook.  */
77 
78 #define POLL_INTERVAL 5
79 
80 /* Helper function to wait a while.  If SCB is non-null, wait on its
81    file descriptor.  Otherwise just wait on a timeout, updating *POLLS.
82    Returns -1 on timeout or interrupt, otherwise the value of select.  */
83 
84 static int
85 wait_for_connect (struct serial *scb, int *polls)
86 {
87   struct timeval t;
88   int n;
89 
90   /* While we wait for the connect to complete,
91      poll the UI so it can update or the user can
92      interrupt.  */
93   if (deprecated_ui_loop_hook && deprecated_ui_loop_hook (0))
94     {
95       errno = EINTR;
96       return -1;
97     }
98 
99   /* Check for timeout.  */
100   if (*polls > tcp_retry_limit * POLL_INTERVAL)
101     {
102       errno = ETIMEDOUT;
103       return -1;
104     }
105 
106   /* Back off to polling once per second after the first POLL_INTERVAL
107      polls.  */
108   if (*polls < POLL_INTERVAL)
109     {
110       t.tv_sec = 0;
111       t.tv_usec = 1000000 / POLL_INTERVAL;
112     }
113   else
114     {
115       t.tv_sec = 1;
116       t.tv_usec = 0;
117     }
118 
119   if (scb)
120     {
121       fd_set rset, wset, eset;
122 
123       FD_ZERO (&rset);
124       FD_SET (scb->fd, &rset);
125       wset = rset;
126       eset = rset;
127 
128       /* POSIX systems return connection success or failure by signalling
129 	 wset.  Windows systems return success in wset and failure in
130 	 eset.
131 
132 	 We must call select here, rather than gdb_select, because
133 	 the serial structure has not yet been initialized - the
134 	 MinGW select wrapper will not know that this FD refers
135 	 to a socket.  */
136       n = select (scb->fd + 1, &rset, &wset, &eset, &t);
137     }
138   else
139     /* Use gdb_select here, since we have no file descriptors, and on
140        Windows, plain select doesn't work in that case.  */
141     n = gdb_select (0, NULL, NULL, NULL, &t);
142 
143   /* If we didn't time out, only count it as one poll.  */
144   if (n > 0 || *polls < POLL_INTERVAL)
145     (*polls)++;
146   else
147     (*polls) += POLL_INTERVAL;
148 
149   return n;
150 }
151 
152 /* Open a tcp socket.  */
153 
154 int
155 net_open (struct serial *scb, const char *name)
156 {
157   char *port_str, hostname[100];
158   int n, port, tmp;
159   int use_udp;
160   struct hostent *hostent;
161   struct sockaddr_in sockaddr;
162 #ifdef USE_WIN32API
163   u_long ioarg;
164 #else
165   int ioarg;
166 #endif
167   int polls = 0;
168 
169   use_udp = 0;
170   if (strncmp (name, "udp:", 4) == 0)
171     {
172       use_udp = 1;
173       name = name + 4;
174     }
175   else if (strncmp (name, "tcp:", 4) == 0)
176     name = name + 4;
177 
178   port_str = strchr (name, ':');
179 
180   if (!port_str)
181     error (_("net_open: No colon in host name!"));  /* Shouldn't ever
182 						       happen.  */
183 
184   tmp = min (port_str - name, (int) sizeof hostname - 1);
185   strncpy (hostname, name, tmp);	/* Don't want colon.  */
186   hostname[tmp] = '\000';	/* Tie off host name.  */
187   port = atoi (port_str + 1);
188 
189   /* Default hostname is localhost.  */
190   if (!hostname[0])
191     strcpy (hostname, "localhost");
192 
193   hostent = gethostbyname (hostname);
194   if (!hostent)
195     {
196       fprintf_unfiltered (gdb_stderr, "%s: unknown host\n", hostname);
197       errno = ENOENT;
198       return -1;
199     }
200 
201   sockaddr.sin_family = PF_INET;
202   sockaddr.sin_port = htons (port);
203   memcpy (&sockaddr.sin_addr.s_addr, hostent->h_addr,
204 	  sizeof (struct in_addr));
205 
206  retry:
207 
208   if (use_udp)
209     scb->fd = socket (PF_INET, SOCK_DGRAM, 0);
210   else
211     scb->fd = socket (PF_INET, SOCK_STREAM, 0);
212 
213   if (scb->fd == -1)
214     return -1;
215 
216   /* Set socket nonblocking.  */
217   ioarg = 1;
218   ioctl (scb->fd, FIONBIO, &ioarg);
219 
220   /* Use Non-blocking connect.  connect() will return 0 if connected
221      already.  */
222   n = connect (scb->fd, (struct sockaddr *) &sockaddr, sizeof (sockaddr));
223 
224   if (n < 0)
225     {
226 #ifdef USE_WIN32API
227       int err = WSAGetLastError();
228 #else
229       int err = errno;
230 #endif
231 
232       /* Maybe we're waiting for the remote target to become ready to
233 	 accept connections.  */
234       if (tcp_auto_retry
235 #ifdef USE_WIN32API
236 	  && err == WSAECONNREFUSED
237 #else
238 	  && err == ECONNREFUSED
239 #endif
240 	  && wait_for_connect (NULL, &polls) >= 0)
241 	{
242 	  close (scb->fd);
243 	  goto retry;
244 	}
245 
246       if (
247 #ifdef USE_WIN32API
248 	  /* Under Windows, calling "connect" with a non-blocking socket
249 	     results in WSAEWOULDBLOCK, not WSAEINPROGRESS.  */
250 	  err != WSAEWOULDBLOCK
251 #else
252 	  err != EINPROGRESS
253 #endif
254 	  )
255 	{
256 	  errno = err;
257 	  net_close (scb);
258 	  return -1;
259 	}
260 
261       /* Looks like we need to wait for the connect.  */
262       do
263 	{
264 	  n = wait_for_connect (scb, &polls);
265 	}
266       while (n == 0);
267       if (n < 0)
268 	{
269 	  net_close (scb);
270 	  return -1;
271 	}
272     }
273 
274   /* Got something.  Is it an error?  */
275   {
276     int res, err;
277     socklen_t len;
278 
279     len = sizeof (err);
280     /* On Windows, the fourth parameter to getsockopt is a "char *";
281        on UNIX systems it is generally "void *".  The cast to "void *"
282        is OK everywhere, since in C "void *" can be implicitly
283        converted to any pointer type.  */
284     res = getsockopt (scb->fd, SOL_SOCKET, SO_ERROR, (void *) &err, &len);
285     if (res < 0 || err)
286       {
287 	/* Maybe the target still isn't ready to accept the connection.  */
288 	if (tcp_auto_retry
289 #ifdef USE_WIN32API
290 	    && err == WSAECONNREFUSED
291 #else
292 	    && err == ECONNREFUSED
293 #endif
294 	    && wait_for_connect (NULL, &polls) >= 0)
295 	  {
296 	    close (scb->fd);
297 	    goto retry;
298 	  }
299 	if (err)
300 	  errno = err;
301 	net_close (scb);
302 	return -1;
303       }
304   }
305 
306   /* Turn off nonblocking.  */
307   ioarg = 0;
308   ioctl (scb->fd, FIONBIO, &ioarg);
309 
310   if (use_udp == 0)
311     {
312       /* Disable Nagle algorithm.  Needed in some cases.  */
313       tmp = 1;
314       setsockopt (scb->fd, IPPROTO_TCP, TCP_NODELAY,
315 		  (char *)&tmp, sizeof (tmp));
316     }
317 
318 #ifdef SIGPIPE
319   /* If we don't do this, then GDB simply exits
320      when the remote side dies.  */
321   signal (SIGPIPE, SIG_IGN);
322 #endif
323 
324   return 0;
325 }
326 
327 void
328 net_close (struct serial *scb)
329 {
330   if (scb->fd == -1)
331     return;
332 
333   close (scb->fd);
334   scb->fd = -1;
335 }
336 
337 int
338 net_read_prim (struct serial *scb, size_t count)
339 {
340   return recv (scb->fd, scb->buf, count, 0);
341 }
342 
343 int
344 net_write_prim (struct serial *scb, const void *buf, size_t count)
345 {
346   return send (scb->fd, buf, count, 0);
347 }
348 
349 int
350 ser_tcp_send_break (struct serial *scb)
351 {
352   /* Send telnet IAC and BREAK characters.  */
353   return (serial_write (scb, "\377\363", 2));
354 }
355 
356 /* Support for "set tcp" and "show tcp" commands.  */
357 
358 static void
359 set_tcp_cmd (char *args, int from_tty)
360 {
361   help_list (tcp_set_cmdlist, "set tcp ", -1, gdb_stdout);
362 }
363 
364 static void
365 show_tcp_cmd (char *args, int from_tty)
366 {
367   help_list (tcp_show_cmdlist, "show tcp ", -1, gdb_stdout);
368 }
369 
370 
371 void
372 _initialize_ser_tcp (void)
373 {
374 #ifdef USE_WIN32API
375   /* Do nothing; the TCP serial operations will be initialized in
376      ser-mingw.c.  */
377 #else
378   struct serial_ops *ops;
379 
380   ops = XMALLOC (struct serial_ops);
381   memset (ops, 0, sizeof (struct serial_ops));
382   ops->name = "tcp";
383   ops->next = 0;
384   ops->open = net_open;
385   ops->close = net_close;
386   ops->readchar = ser_base_readchar;
387   ops->write = ser_base_write;
388   ops->flush_output = ser_base_flush_output;
389   ops->flush_input = ser_base_flush_input;
390   ops->send_break = ser_tcp_send_break;
391   ops->go_raw = ser_base_raw;
392   ops->get_tty_state = ser_base_get_tty_state;
393   ops->copy_tty_state = ser_base_copy_tty_state;
394   ops->set_tty_state = ser_base_set_tty_state;
395   ops->print_tty_state = ser_base_print_tty_state;
396   ops->noflush_set_tty_state = ser_base_noflush_set_tty_state;
397   ops->setbaudrate = ser_base_setbaudrate;
398   ops->setstopbits = ser_base_setstopbits;
399   ops->drain_output = ser_base_drain_output;
400   ops->async = ser_base_async;
401   ops->read_prim = net_read_prim;
402   ops->write_prim = net_write_prim;
403   serial_add_interface (ops);
404 #endif /* USE_WIN32API */
405 
406   add_prefix_cmd ("tcp", class_maintenance, set_tcp_cmd, _("\
407 TCP protocol specific variables\n\
408 Configure variables specific to remote TCP connections"),
409 		  &tcp_set_cmdlist, "set tcp ",
410 		  0 /* allow-unknown */, &setlist);
411   add_prefix_cmd ("tcp", class_maintenance, show_tcp_cmd, _("\
412 TCP protocol specific variables\n\
413 Configure variables specific to remote TCP connections"),
414 		  &tcp_show_cmdlist, "show tcp ",
415 		  0 /* allow-unknown */, &showlist);
416 
417   add_setshow_boolean_cmd ("auto-retry", class_obscure,
418 			   &tcp_auto_retry, _("\
419 Set auto-retry on socket connect"), _("\
420 Show auto-retry on socket connect"),
421 			   NULL, NULL, NULL,
422 			   &tcp_set_cmdlist, &tcp_show_cmdlist);
423 
424   add_setshow_uinteger_cmd ("connect-timeout", class_obscure,
425 			    &tcp_retry_limit, _("\
426 Set timeout limit for socket connection"), _("\
427 Show timeout limit for socket connection"),
428 			   NULL, NULL, NULL,
429 			   &tcp_set_cmdlist, &tcp_show_cmdlist);
430 }
431