aboutsummaryrefslogtreecommitdiffstats
path: root/dist/gdb/patches/gdb-ipv6.patch
diff options
context:
space:
mode:
Diffstat (limited to 'dist/gdb/patches/gdb-ipv6.patch')
-rw-r--r--dist/gdb/patches/gdb-ipv6.patch1037
1 files changed, 0 insertions, 1037 deletions
diff --git a/dist/gdb/patches/gdb-ipv6.patch b/dist/gdb/patches/gdb-ipv6.patch
deleted file mode 100644
index d595f7edd16..00000000000
--- a/dist/gdb/patches/gdb-ipv6.patch
+++ /dev/null
@@ -1,1037 +0,0 @@
-diff -Nru a/gdb-7.6.1/gdb/gdbserver/gdbreplay.c b/gdb-7.6.1/gdb/gdbserver/gdbreplay.c
---- a/gdb-7.6.1/gdb/gdbserver/gdbreplay.c 2012-08-22 13:05:02 -0700
-+++ b/gdb-7.6.1/gdb/gdbserver/gdbreplay.c 2013-04-15 03:20:40 -0700
-@@ -189,14 +189,41 @@ remote_close (void)
- static void
- remote_open (char *name)
- {
-- if (!strchr (name, ':'))
-+ char *port_str;
-+ char *host_start, *host_end;
-+
-+ host_start = name;
-+ if (host_start[0] == '[')
- {
-- fprintf (stderr, "%s: Must specify tcp connection as host:addr\n", name);
-- fflush (stderr);
-- exit (1);
-+ ++host_start;
-+ host_end = strchr (host_start, ']');
-+ if (host_end == NULL)
-+ {
-+ fprintf (stderr, "Mismatched `[' in hostname.");
-+ fflush (stderr);
-+ exit (1);
-+ }
-+ port_str = host_end + 1;
-+ if (*port_str != ':')
-+ {
-+ fprintf (stderr, "Missing port after hostname, specify tcp connection as host:port or [host]:port.");
-+ fflush (stderr);
-+ exit (1);
-+ }
- }
- else
- {
-+ port_str = strchr (name, ':');
-+ host_end = port_str;
-+ if (port_str == NULL)
-+ {
-+ fprintf (stderr, "Missing port after hostname, specify tcp connection as host:port or [host]:port.");
-+ fflush (stderr);
-+ exit(1);
-+ }
-+ }
-+
-+ {
- #ifdef USE_WIN32API
- static int winsock_initialized;
- #endif
-diff -Nru a/gdb-7.6.1/gdb/gdbserver/remote-utils.c b/gdb-7.6.1/gdb/gdbserver/remote-utils.c
---- a/gdb-7.6.1/gdb/gdbserver/remote-utils.c 2012-04-28 23:28:30 -0700
-+++ b/gdb-7.6.1/gdb/gdbserver/remote-utils.c 2013-04-16 06:25:07 -0700
-@@ -16,6 +16,8 @@
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-+#define _WIN32_WINNT 0x501
-+
- #include "server.h"
- #include "terminal.h"
- #include "target.h"
-@@ -63,6 +65,13 @@
-
- #if USE_WIN32API
- #include <winsock2.h>
-+#include <ws2tcpip.h>
-+#else
-+#include <netinet/in.h> /* sockaddr_in{} and other Internet defns */
-+#endif
-+
-+#ifndef SOL_IPV6
-+#define SOL_IPV6 IPPROTO_IPV6
- #endif
-
- #if __QNX__
-@@ -109,7 +118,7 @@
- static int remote_is_stdio = 0;
-
- gdb_fildes_t remote_desc = INVALID_DESCRIPTOR;
--gdb_fildes_t listen_desc = INVALID_DESCRIPTOR;
-+gdb_fildes_t *listening_sockets = NULL;
-
- /* FIXME headerize? */
- extern int using_threads;
-@@ -156,15 +165,17 @@
- static int
- handle_accept_event (int err, gdb_client_data client_data)
- {
-- struct sockaddr_in sockaddr;
-+ struct sockaddr_storage address;
- socklen_t tmp;
-+ char back_host[64], back_port[16];
-+ gdb_fildes_t listen_desc = *(gdb_fildes_t *)client_data;
-
- if (debug_threads)
- fprintf (stderr, "handling possible accept event\n");
-
-- tmp = sizeof (sockaddr);
-- remote_desc = accept (listen_desc, (struct sockaddr *) &sockaddr, &tmp);
-- if (remote_desc == -1)
-+ tmp = (socklen_t) sizeof (address);
-+ remote_desc = accept (listen_desc, (struct sockaddr *) &address, &tmp);
-+ if (remote_desc == INVALID_DESCRIPTOR)
- perror_with_name ("Accept failed");
-
- /* Enable TCP keep alive process. */
-@@ -178,27 +189,55 @@
- setsockopt (remote_desc, IPPROTO_TCP, TCP_NODELAY,
- (char *) &tmp, sizeof (tmp));
-
-+ if (listening_sockets)
-+ {
-+ /* We assume that all sockets have been registered, and none triggers
-+ while doing this. This is true in the current single threaded
-+ implementation. */
-+ gdb_fildes_t *l_sock = listening_sockets;
-+ for (++l_sock; *l_sock != INVALID_DESCRIPTOR; ++l_sock)
-+ {
- #ifndef USE_WIN32API
-- signal (SIGPIPE, SIG_IGN); /* If we don't do this, then gdbserver simply
-- exits when the remote side dies. */
-+ signal (SIGPIPE, SIG_IGN); /* If we don't do this, then gdbserver simply
-+ exits when the remote side dies. */
- #endif
-
-- if (run_once)
-- {
-+ if (run_once)
-+ {
- #ifndef USE_WIN32API
-- close (listen_desc); /* No longer need this */
-+ close (*l_sock); /* No longer need this */
- #else
-- closesocket (listen_desc); /* No longer need this */
-+ closesocket (*l_sock); /* No longer need this */
- #endif
-- }
-+ }
-
-- /* Even if !RUN_ONCE no longer notice new connections. Still keep the
-+ /* Even if !RUN_ONCE no longer notice new connections. Still keep the
- descriptor open for add_file_handler to wait for a new connection. */
-- delete_file_handler (listen_desc);
-+ delete_file_handler (*l_sock);
-+ }
-+ if (run_once)
-+ {
-+ free(listening_sockets);
-+ listening_sockets = NULL;
-+ }
-+ }
-
- /* Convert IP address to string. */
-- fprintf (stderr, "Remote debugging from host %s\n",
-- inet_ntoa (sockaddr.sin_addr));
-+ if (getnameinfo ((struct sockaddr *) &address,
-+ (socklen_t) sizeof (address),
-+ back_host, (socklen_t) sizeof (back_host),
-+ back_port, (socklen_t) sizeof (back_port),
-+ NI_NUMERICHOST | NI_NUMERICSERV))
-+ {
-+ fprintf (stderr, "Error detecting originating address, trying anyway\n");
-+ }
-+ else
-+ {
-+ back_host[sizeof (back_host) - 1] = 0;
-+ back_port[sizeof (back_port) - 1] = 0;
-+ fprintf (stderr, "Remote debugging from host %s port %s\n",
-+ back_host, back_port);
-+ }
-
- enable_async_notification (remote_desc);
-
-@@ -224,12 +263,15 @@
- {
- char *port_str;
- #ifdef USE_WIN32API
-- static int winsock_initialized;
-+ static int winsock_initialized = 0;
- #endif
-- int port;
-- struct sockaddr_in sockaddr;
-- socklen_t tmp;
-- char *port_end;
-+ char *host_start, *host_end;
-+ struct addrinfo hints, *ainfo, *ainfo0;
-+ gdb_fildes_t *socktable = NULL;
-+ gdb_fildes_t s = INVALID_DESCRIPTOR;
-+ int nsock = 0, socktable_size = 0, err, port = 0;
-+ char *host_str = NULL;
-+ char back_host[128], back_port[32];
-
- remote_is_stdio = 0;
- if (strcmp (name, STDIO_CONNECTION_NAME) == 0)
-@@ -249,8 +291,24 @@
- return;
- }
-
-- port = strtoul (port_str + 1, &port_end, 10);
-- if (port_str[1] == '\0' || *port_end != '\0')
-+ host_start = name;
-+ if (host_start[0] == '[')
-+ {
-+ ++host_start;
-+ host_end = strchr (host_start, ']');
-+ if (host_end == NULL)
-+ fatal ("Mismatched `[' in hostname.");
-+ port_str = host_end + 1;
-+ if (*port_str != ':')
-+ fatal ("Missing port after hostname.");
-+ }
-+ else
-+ {
-+ port_str = strchr (name, ':');
-+ host_end = port_str;
-+ }
-+
-+ if (port_str[1] == '\0')
- fatal ("Bad port argument: %s", name);
-
- #ifdef USE_WIN32API
-@@ -263,24 +321,181 @@
- }
- #endif
-
-- listen_desc = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP);
-- if (listen_desc == -1)
-- perror_with_name ("Can't open socket");
-+ if (host_start < host_end)
-+ {
-+ host_str = strdup(host_start);
-+ host_str[host_end - host_start] = 0;
-+ }
-+ ++port_str;
-
-- /* Allow rapid reuse of this port. */
-- tmp = 1;
-- setsockopt (listen_desc, SOL_SOCKET, SO_REUSEADDR, (char *) &tmp,
-- sizeof (tmp));
-+ memset(&hints, 0, sizeof(hints));
-+ hints.ai_family = PF_UNSPEC;
-+ hints.ai_socktype = SOCK_STREAM;
-+ hints.ai_flags = AI_PASSIVE;
-+
-+ err = getaddrinfo(host_str, port_str, &hints, &ainfo0);
-+ if (err)
-+ fatal ("%s for %s", gai_strerror(err), name);
-+
-+ for (ainfo = ainfo0; ainfo; ainfo = ainfo->ai_next)
-+ {
-+ int current_port, tmp;
-+
-+ if (getnameinfo ((struct sockaddr *) ainfo->ai_addr,
-+ (socklen_t) ainfo->ai_addrlen,
-+ back_host, (socklen_t) sizeof (back_host),
-+ back_port, (socklen_t) sizeof (back_port),
-+ NI_NUMERICHOST | NI_NUMERICSERV))
-+ {
-+ back_host[0] = 0;
-+ back_port[0] = 0;
-+ }
-+ else
-+ {
-+ back_host[sizeof (back_host) - 1] = 0;
-+ back_port[sizeof (back_port) - 1] = 0;
-+ }
-+
-+ switch (ainfo->ai_addr->sa_family)
-+ {
-+ case AF_INET:
-+ current_port = ntohs (((struct sockaddr_in *) ainfo->ai_addr)
-+ ->sin_port);
-+ break;
-+ case AF_INET6:
-+ current_port = ntohs (((struct sockaddr_in6 *) ainfo->ai_addr)
-+ ->sin6_port);
-+ break;
-+ default:
-+ fatal ("Unexpected address family: %d for %s %s",
-+ ainfo->ai_addr->sa_family,back_host,back_port);
-+ }
-+
-+ if (port != 0 && current_port == 0)
-+ {
-+ /* Use the same port for all protocol/interfaces. */
-+ switch (ainfo->ai_addr->sa_family)
-+ {
-+ case AF_INET:
-+ ((struct sockaddr_in *) ainfo->ai_addr)->sin_port =
-+ htons(port);
-+ break;
-+ case AF_INET6:
-+ ((struct sockaddr_in6 *) ainfo->ai_addr)->sin6_port =
-+ htons(port);
-+ break;
-+ }
-+ }
-+ s = socket(ainfo->ai_family, ainfo->ai_socktype, ainfo->ai_protocol);
-+ if (s < 0)
-+ continue;
-+
-+ /* Allow rapid reuse of this port. */
-+ tmp = 1;
-+ if (setsockopt (s, SOL_SOCKET, SO_REUSEADDR, (char *) &tmp,
-+ (socklen_t) sizeof (tmp)) != 0)
-+ {
-+ fprintf (stderr, "Trying to bind %s port %s.\n",
-+ back_host, back_port);
-+ perror("setsockopt(s, SOL_SOCKET, SO_REUSEADDR,[1],4)");
-+ }
-+#ifdef IPV6_V6ONLY
-+ if (ainfo->ai_addr->sa_family == AF_INET6
-+ && setsockopt (s, SOL_IPV6, IPV6_V6ONLY, (char *) &tmp,
-+ (socklen_t) sizeof (tmp)) != 0)
-+ {
-+ fprintf (stderr, "Trying to bind %s port %s.\n",
-+ back_host, back_port);
-+ perror("setsockopt(s, SOL_IPV6, IPV6_V6ONLY,[1],4)");
-+ }
-+#endif
-+
-+ if (bind (s, ainfo->ai_addr, ainfo->ai_addrlen) != 0)
-+ {
-+ fprintf (stderr, "Trying to bind %s port %s.\n",
-+ back_host, back_port);
-+ perror ("bind failed");
-+ close (s);
-+ s = -1;
-+ continue;
-+ }
-+
-+ if (listen (s, 1) != 0)
-+ {
-+ fprintf (stderr, "Trying to bind %s port %s.\n",
-+ back_host, back_port);
-+ perror ("Can't listen to a bound socket");
-+ close (s);
-+ s = -1;
-+ continue;
-+ }
-+
-+ {
-+ struct sockaddr_storage address;
-+ socklen_t alen = (socklen_t) sizeof (address);
-+
-+ if (getsockname (s, (struct sockaddr *) &address, &alen))
-+ fatal ("Failed to get socket address %s, on soket bound to %s port %s.",
-+ strerror (errno), back_host, back_port);
-+
-+ if (port == 0)
-+ /* Try to recover the port set by the kernel. */
-+ switch (address.ss_family)
-+ {
-+ case AF_INET:
-+ port = ntohs (((struct sockaddr_in *) &address)->sin_port);
-+ break;
-+ case AF_INET6:
-+ port = ntohs (((struct sockaddr_in6 *) &address)->sin6_port);
-+ break;
-+ default:
-+ fatal ("Unexpected address family: %d", address.ss_family);
-+ }
-+
-+ if (getnameinfo ((struct sockaddr *) &address,
-+ (socklen_t) sizeof (address),
-+ back_host, (socklen_t) sizeof (back_host),
-+ back_port, (socklen_t) sizeof (back_port),
-+ NI_NUMERICHOST | NI_NUMERICSERV))
-+ {
-+ fprintf (stderr, "Error detecting bound address.\n");
-+ }
-+ else
-+ {
-+ back_host[sizeof (back_host) - 1] = 0;
-+ back_port[sizeof (back_port) - 1] = 0;
-+ fprintf (stderr, "Sucessfully bound %s port %s\n",
-+ back_host, back_port);
-+ }
-+ }
-
-- sockaddr.sin_family = PF_INET;
-- sockaddr.sin_port = htons (port);
-- sockaddr.sin_addr.s_addr = INADDR_ANY;
--
-- if (bind (listen_desc, (struct sockaddr *) &sockaddr, sizeof (sockaddr))
-- || listen (listen_desc, 1))
-- perror_with_name ("Can't bind address");
-+ if (socktable_size < nsock + 3)
-+ {
-+ socktable = xrealloc (socktable,
-+ (nsock + 10) * sizeof (gdb_fildes_t));
-+ socktable[0] = INVALID_DESCRIPTOR;
-+ }
-+ socktable[++nsock] = s;
-+ }
-+
-+ freeaddrinfo (ainfo0);
-+ free (host_str);
-+
-+ if (nsock == 0)
-+ fatal("Failed to bind any socket.");
-+
-+ /* Bound socktable from both ends, so an inner pointer can still
-+ find the whole array. */
-+ socktable[++nsock] = INVALID_DESCRIPTOR;
-
- transport_is_reliable = 1;
-+ fprintf (stderr, "Listening on port %d\n", port);
-+ fflush (stderr);
-+ transport_is_reliable = 1;
-+ if (listening_sockets)
-+ fatal ("Multiple concurrent remote_open not supported.");
-+
-+ listening_sockets = socktable;
- }
-
- /* Open a connection to a remote debugger.
-@@ -290,8 +505,24 @@
- remote_open (char *name)
- {
- char *port_str;
-+ char *host_start, *host_end;
-
-- port_str = strchr (name, ':');
-+ host_start = name;
-+ if (host_start[0] == '[')
-+ {
-+ ++host_start;
-+ host_end = strchr (host_start, ']');
-+ if (host_end == NULL)
-+ fatal ("Mismatched `[' in hostname.");
-+ port_str = host_end + 1;
-+ if (*port_str != ':')
-+ fatal ("Missing port after hostname.");
-+ }
-+ else
-+ {
-+ port_str = strchr (name, ':');
-+ host_end = port_str;
-+ }
- #ifdef USE_WIN32API
- if (port_str == NULL)
- error ("Only <host>:<port> is supported on this platform.");
-@@ -381,22 +612,17 @@
- #endif /* USE_WIN32API */
- else
- {
-- int port;
-- socklen_t len;
-- struct sockaddr_in sockaddr;
--
-- len = sizeof (sockaddr);
-- if (getsockname (listen_desc,
-- (struct sockaddr *) &sockaddr, &len) < 0
-- || len < sizeof (sockaddr))
-- perror_with_name ("Can't determine port");
-- port = ntohs (sockaddr.sin_port);
-+ int isock;
-
-- fprintf (stderr, "Listening on port %d\n", port);
-- fflush (stderr);
--
-- /* Register the event loop handler. */
-- add_file_handler (listen_desc, handle_accept_event, NULL);
-+ if (! listening_sockets)
-+ fatal ("Listening_sockets not initialized (missing call to remote_prepare).");
-+ for (isock = 1; listening_sockets[isock] != INVALID_DESCRIPTOR; ++isock)
-+ {
-+ /* This assumes the loop ends before any of the handlers is called.
-+ This is true in the current non threaded implementation. */
-+ add_file_handler (listening_sockets[isock], handle_accept_event,
-+ listening_sockets + isock);
-+ }
- }
- }
-
-diff -Nru a/gdb-7.6.1/gdb/ser-tcp.c b/gdb-7.6.1/gdb/ser-tcp.c
---- a/gdb-7.6.1/gdb/ser-tcp.c 2012-01-04 00:17:10 -0800
-+++ b/gdb-7.6.1/gdb/ser-tcp.c 2013-04-15 03:20:40 -0700
-@@ -37,7 +37,9 @@
- #include <sys/time.h>
-
- #ifdef USE_WIN32API
-+#define _WIN32_WINNT 0x0501
- #include <winsock2.h>
-+#include <ws2tcpip.h>
- #ifndef ETIMEDOUT
- #define ETIMEDOUT WSAETIMEDOUT
- #endif
-@@ -49,6 +51,7 @@
- #include <netdb.h>
- #include <sys/socket.h>
- #include <netinet/tcp.h>
-+#include <netinet/in.h>
- #endif
-
- #include <signal.h>
-@@ -78,76 +81,49 @@ static unsigned int tcp_retry_limit = 15
-
- #define POLL_INTERVAL 5
-
--/* Helper function to wait a while. If SCB is non-null, wait on its
-- file descriptor. Otherwise just wait on a timeout, updating *POLLS.
-- Returns -1 on timeout or interrupt, otherwise the value of select. */
-+enum {
-+ ADDR_DROP,
-+ ADDR_RECONNECT,
-+ ADDR_WAIT,
-+ ADDR_SUCCESS
-+};
-
-+/* Tries to connect to a socket */
- static int
--wait_for_connect (struct serial *scb, int *polls)
-+check_sock_err (int fd)
- {
-- struct timeval t;
-- int n;
--
-- /* While we wait for the connect to complete,
-- poll the UI so it can update or the user can
-- interrupt. */
-- if (deprecated_ui_loop_hook && deprecated_ui_loop_hook (0))
-- {
-- errno = EINTR;
-- return -1;
-- }
--
-- /* Check for timeout. */
-- if (*polls > tcp_retry_limit * POLL_INTERVAL)
-- {
-- errno = ETIMEDOUT;
-- return -1;
-- }
--
-- /* Back off to polling once per second after the first POLL_INTERVAL
-- polls. */
-- if (*polls < POLL_INTERVAL)
-- {
-- t.tv_sec = 0;
-- t.tv_usec = 1000000 / POLL_INTERVAL;
-- }
-- else
-- {
-- t.tv_sec = 1;
-- t.tv_usec = 0;
-- }
-+ int res, err;
-+ socklen_t len;
-
-- if (scb)
-+ len = sizeof (err);
-+ /* On Windows, the fourth parameter to getsockopt is a "char *";
-+ on UNIX systems it is generally "void *". The cast to "void *"
-+ is OK everywhere, since in C "void *" can be implicitly
-+ converted to any pointer type. */
-+ res = getsockopt (fd, SOL_SOCKET, SO_ERROR, (void *) &err, &len);
-+ if (res < 0 || err)
- {
-- fd_set rset, wset, eset;
--
-- FD_ZERO (&rset);
-- FD_SET (scb->fd, &rset);
-- wset = rset;
-- eset = rset;
--
-- /* POSIX systems return connection success or failure by signalling
-- wset. Windows systems return success in wset and failure in
-- eset.
--
-- We must call select here, rather than gdb_select, because
-- the serial structure has not yet been initialized - the
-- MinGW select wrapper will not know that this FD refers
-- to a socket. */
-- n = select (scb->fd + 1, &rset, &wset, &eset, &t);
-+ /* Maybe the target still isn't ready to accept the connection. */
-+ if (tcp_auto_retry
-+ #ifdef USE_WIN32API
-+ && err == WSAECONNREFUSED
-+ #else
-+ && err == ECONNREFUSED
-+ #endif
-+ )
-+ {
-+ close (fd);
-+ return ADDR_RECONNECT;
-+ }
-+ else
-+ {
-+ if (err)
-+ errno = err;
-+ close (fd);
-+ return ADDR_DROP;
-+ }
- }
-- else
-- /* Use gdb_select here, since we have no file descriptors, and on
-- Windows, plain select doesn't work in that case. */
-- n = gdb_select (0, NULL, NULL, NULL, &t);
--
-- /* If we didn't time out, only count it as one poll. */
-- if (n > 0 || *polls < POLL_INTERVAL)
-- (*polls)++;
-- else
-- (*polls) += POLL_INTERVAL;
--
-- return n;
-+ return ADDR_SUCCESS;
- }
-
- /* Open a tcp socket. */
-@@ -155,18 +131,24 @@ wait_for_connect (struct serial *scb, in
- int
- net_open (struct serial *scb, const char *name)
- {
-- char *port_str, hostname[100];
-- int n, port, tmp;
-+ char *port_str, hostname[100], *name_end;
-+ int n = 0, tmp;
- int use_udp;
- struct hostent *hostent;
-- struct sockaddr_in sockaddr;
-+ struct addrinfo hints, *ainfo, *ainfo0, *ainfo_reconnect, *ainfo_old,
-+ *ainfo_tmp;
-+ struct sockaddr_storage address;
-+ int max_w_socks = 0, n_w_socks = 0;
-+ int *waiting_socks = NULL;
- #ifdef USE_WIN32API
- u_long ioarg;
- #else
- int ioarg;
- #endif
- int polls = 0;
-+ int err, fd = -1;
-
-+ scb->fd = -1;
- use_udp = 0;
- if (strncmp (name, "udp:", 4) == 0)
- {
-@@ -176,134 +158,286 @@ net_open (struct serial *scb, const char
- else if (strncmp (name, "tcp:", 4) == 0)
- name = name + 4;
-
-- port_str = strchr (name, ':');
--
-- if (!port_str)
-- error (_("net_open: No colon in host name!")); /* Shouldn't ever
-+ if (name[0]=='[')
-+ {
-+ ++name;
-+ name_end = strchr(name, ']');
-+ if (name_end == NULL)
-+ error (_("net_open: Mismatched '['"));
-+ port_str = name_end+1;
-+ } else {
-+ port_str = strchr (name, ':');
-+ name_end = port_str;
-+ }
-+ if (!port_str || port_str[0] !=':')
-+ error (_("net_open: No colon after host name!")); /* Shouldn't ever
- happen. */
-
-- tmp = min (port_str - name, (int) sizeof hostname - 1);
-- strncpy (hostname, name, tmp); /* Don't want colon. */
-- hostname[tmp] = '\000'; /* Tie off host name. */
-- port = atoi (port_str + 1);
--
-- /* Default hostname is localhost. */
-- if (!hostname[0])
-- strcpy (hostname, "localhost");
--
-- hostent = gethostbyname (hostname);
-- if (!hostent)
-+ tmp = min (name_end - name, (int) sizeof hostname - 1);
-+ /* Default hostname is localhost. Keeping this but NULL should also work. */
-+ if (!name[0])
- {
-- fprintf_unfiltered (gdb_stderr, "%s: unknown host\n", hostname);
-- errno = ENOENT;
-- return -1;
-+ strcpy (hostname, "localhost");
- }
--
-- sockaddr.sin_family = PF_INET;
-- sockaddr.sin_port = htons (port);
-- memcpy (&sockaddr.sin_addr.s_addr, hostent->h_addr,
-- sizeof (struct in_addr));
--
-- retry:
--
-- if (use_udp)
-- scb->fd = socket (PF_INET, SOCK_DGRAM, 0);
- else
-- scb->fd = socket (PF_INET, SOCK_STREAM, 0);
--
-- if (scb->fd == -1)
-- return -1;
-+ {
-+ strncpy (hostname, name, tmp); /* Don't want colon. */
-+ hostname[tmp] = '\000'; /* Tie off host name. */
-+ }
-+ ++port_str;
-
-- /* Set socket nonblocking. */
-- ioarg = 1;
-- ioctl (scb->fd, FIONBIO, &ioarg);
-+
-+ memset(&hints, 0, sizeof(hints));
-+ hints.ai_family = PF_UNSPEC;
-+ if (use_udp)
-+ hints.ai_socktype = SOCK_DGRAM;
-+ else
-+ hints.ai_socktype = SOCK_STREAM;
-
-- /* Use Non-blocking connect. connect() will return 0 if connected
-- already. */
-- n = connect (scb->fd, (struct sockaddr *) &sockaddr, sizeof (sockaddr));
-+ err = getaddrinfo(hostname, port_str, &hints, &ainfo0);
-+ if (err)
-+ {
-+ fprintf_unfiltered (gdb_stderr, "%s: connecting to %s on port %s\n",
-+ gai_strerror(err), hostname, port_str);
-+ errno = ENOENT;
-+ return -1;
-+ }
-
-- if (n < 0)
-+ do
- {
--#ifdef USE_WIN32API
-- int err = WSAGetLastError();
--#else
-- int err = errno;
--#endif
-+ ainfo = ainfo0;
-+ ainfo_old = NULL;
-+ while (ainfo)
-+ {
-+ int op_to_do, connect_ret;
-+
-+ ainfo_old = ainfo;
-+ fd = socket (ainfo->ai_family, ainfo->ai_socktype,
-+ ainfo->ai_protocol);
-+
-+ if (fd == -1)
-+ {
-+ ainfo = ainfo->ai_next;
-+ continue;
-+ }
-+
-+ /* Set socket nonblocking. */
-+ ioarg = 1;
-+ ioctl (fd, FIONBIO, &ioarg);
-+
-+ /* Use Non-blocking connect. connect() will return 0 if connected
-+ already. */
-+ connect_ret = connect (fd, ainfo->ai_addr, ainfo->ai_addrlen);
-
-- /* Maybe we're waiting for the remote target to become ready to
-- accept connections. */
-- if (tcp_auto_retry
-+ if (connect_ret < 0)
-+ {
- #ifdef USE_WIN32API
-- && err == WSAECONNREFUSED
-+ int err = WSAGetLastError();
- #else
-- && err == ECONNREFUSED
-+ int err = errno;
- #endif
-- && wait_for_connect (NULL, &polls) >= 0)
-- {
-- close (scb->fd);
-- goto retry;
-- }
-
-- if (
--#ifdef USE_WIN32API
-- /* Under Windows, calling "connect" with a non-blocking socket
-- results in WSAEWOULDBLOCK, not WSAEINPROGRESS. */
-- err != WSAEWOULDBLOCK
--#else
-- err != EINPROGRESS
--#endif
-- )
-- {
-- errno = err;
-- net_close (scb);
-- return -1;
-- }
--
-- /* Looks like we need to wait for the connect. */
-- do
-- {
-- n = wait_for_connect (scb, &polls);
-- }
-- while (n == 0);
-- if (n < 0)
-- {
-- net_close (scb);
-- return -1;
-- }
-+ /* Maybe we're waiting for the remote target to become ready to
-+ accept connections. */
-+ if (tcp_auto_retry
-+ #ifdef USE_WIN32API
-+ && err == WSAECONNREFUSED
-+ #else
-+ && err == ECONNREFUSED
-+ #endif
-+ )
-+ {
-+ close (fd);
-+ op_to_do = ADDR_RECONNECT;
-+ }
-+ else if (
-+ #ifdef USE_WIN32API
-+ /* Under Windows, calling "connect" with a non-blocking socket
-+ results in WSAEWOULDBLOCK, not WSAEINPROGRESS. */
-+ err != WSAEWOULDBLOCK
-+ #else
-+ err != EINPROGRESS
-+ #endif
-+ )
-+ {
-+ close (fd);
-+ op_to_do = ADDR_DROP;
-+ }
-+ else
-+ {
-+ op_to_do = ADDR_WAIT;
-+ }
-+ }
-+ else
-+ {
-+ op_to_do = check_sock_err(fd);
-+ }
-+ switch (op_to_do)
-+ {
-+ case ADDR_DROP:
-+ break;
-+ case ADDR_RECONNECT:
-+ ainfo_tmp = ainfo->ai_next;
-+ ainfo->ai_next = ainfo_reconnect;
-+ ainfo_reconnect->ai_next = ainfo;
-+ ainfo = ainfo_tmp;
-+ ainfo_old = NULL;
-+ break;
-+ case ADDR_WAIT:
-+ /* Looks like we need to wait for the connect. */
-+ if (n_w_socks >= max_w_socks)
-+ {
-+ max_w_socks += 10;
-+ waiting_socks= xrealloc (waiting_socks, max_w_socks
-+ * sizeof(*waiting_socks));
-+ }
-+ waiting_socks[n_w_socks++] = fd;
-+ break;
-+ case ADDR_SUCCESS:
-+ break;
-+ default:
-+ fatal (_("Unexpected value for try_connect in net_open."));
-+ }
-+ if (ainfo_old)
-+ {
-+ ainfo = ainfo_old->ai_next;
-+ ainfo_old->ai_next = NULL;
-+ freeaddrinfo (ainfo_old);
-+ }
-+ if (op_to_do == ADDR_SUCCESS)
-+ break;
-+ fd = -1;
-+ }
-+ ainfo0 = ainfo_reconnect;
-+ ainfo_reconnect = NULL;
-+
-+ if (fd != -1 || !(ainfo0 != NULL || n_w_socks != 0))
-+ break;
-+
-+ do
-+ {
-+ struct timeval t;
-+ int max_fd;
-+ fd_set rset;
-+
-+ /* While we wait for the connect to complete,
-+ poll the UI so it can update or the user can
-+ interrupt. */
-+ if (deprecated_ui_loop_hook && deprecated_ui_loop_hook (0))
-+ {
-+ errno = EINTR;
-+ return -1;
-+ }
-+
-+ /* Check for timeout. */
-+ if (polls > tcp_retry_limit * POLL_INTERVAL)
-+ {
-+ errno = ETIMEDOUT;
-+ return -1;
-+ }
-+
-+ /* Back off to polling once per second after the first POLL_INTERVAL
-+ polls. */
-+ if (polls < POLL_INTERVAL)
-+ {
-+ t.tv_sec = 0;
-+ t.tv_usec = 1000000 / POLL_INTERVAL;
-+ }
-+ else
-+ {
-+ t.tv_sec = 1;
-+ t.tv_usec = 0;
-+ }
-+
-+ max_fd=-1;
-+ if (n_w_socks)
-+ {
-+ int ifd;
-+
-+ FD_ZERO (&rset);
-+ for (ifd = 0; ifd < n_w_socks; ++ifd)
-+ {
-+ if (waiting_socks[ifd] != -1)
-+ {
-+ FD_SET (waiting_socks[ifd], &rset);
-+ if (max_fd < waiting_socks[ifd])
-+ max_fd = waiting_socks[ifd];
-+ }
-+ }
-+ }
-+ if (max_fd != -1)
-+ {
-+ int ifd;
-+ fd_set wset, eset;
-+ wset = rset;
-+ eset = rset;
-+
-+ /* POSIX systems return connection success or failure by signalling
-+ wset. Windows systems return success in wset and failure in
-+ eset.
-+
-+ We must call select here, rather than gdb_select, because
-+ the serial structure has not yet been initialized - the
-+ MinGW select wrapper will not know that this FD refers
-+ to a socket. */
-+ n = select (max_fd + 1, &rset, &wset, &eset, &t);
-+ if (n > 0)
-+ for (ifd = 0; ifd < n_w_socks && fd == -1; ++ifd)
-+ if (FD_ISSET(waiting_socks[ifd], &rset)
-+ || FD_ISSET(waiting_socks[ifd], &wset)
-+ || FD_ISSET(waiting_socks[ifd], &eset))
-+ {
-+ int op_to_do;
-+
-+ op_to_do = check_sock_err(waiting_socks[ifd]);
-+ switch (op_to_do)
-+ {
-+ case ADDR_RECONNECT:
-+ //waiting_socks[ifd] = -1;
-+ break;
-+ case ADDR_DROP:
-+ //waiting_socks[ifd] = -1;
-+ break;
-+ case ADDR_WAIT:
-+ break;
-+ case ADDR_SUCCESS:
-+ fd = waiting_socks[ifd];
-+ break;
-+ default:
-+ fatal (_("Unexpected value for try_connect in net_open."));
-+ }
-+ }
-+ }
-+ else
-+ /* Use gdb_select here, since we have no file descriptors, and on
-+ Windows, plain select doesn't work in that case. */
-+ n = gdb_select (0, NULL, NULL, NULL, &t);
-+
-+ /* If we didn't time out, only count it as one poll. */
-+ if (n > 0 || polls < POLL_INTERVAL)
-+ polls++;
-+ else
-+ polls += POLL_INTERVAL;
-+ }
-+ while (fd == -1 && n == 0 && ainfo0 == NULL);
- }
-+ while (fd == -1 && n >= 0);
-
-- /* Got something. Is it an error? */
-- {
-- int res, err;
-- socklen_t len;
--
-- len = sizeof (err);
-- /* On Windows, the fourth parameter to getsockopt is a "char *";
-- on UNIX systems it is generally "void *". The cast to "void *"
-- is OK everywhere, since in C "void *" can be implicitly
-- converted to any pointer type. */
-- res = getsockopt (scb->fd, SOL_SOCKET, SO_ERROR, (void *) &err, &len);
-- if (res < 0 || err)
-- {
-- /* Maybe the target still isn't ready to accept the connection. */
-- if (tcp_auto_retry
--#ifdef USE_WIN32API
-- && err == WSAECONNREFUSED
--#else
-- && err == ECONNREFUSED
--#endif
-- && wait_for_connect (NULL, &polls) >= 0)
-- {
-- close (scb->fd);
-- goto retry;
-- }
-- if (err)
-- errno = err;
-- net_close (scb);
-- return -1;
-- }
-- }
-+ freeaddrinfo (ainfo0);
-+ if (waiting_socks)
-+ {
-+ int ifd;
-+
-+ for (ifd = 0; ifd < n_w_socks && fd == -1; ++ifd)
-+ if (waiting_socks[ifd] != fd && waiting_socks[ifd] != -1)
-+ close (waiting_socks[ifd]);
-+ }
-+ free (waiting_socks);
-+
-+ if (fd == -1)
-+ return -1;
-
-+ scb->fd = fd;
- /* Turn off nonblocking. */
- ioarg = 0;
- ioctl (scb->fd, FIONBIO, &ioarg);