+ /* Got something. Is it an error? */
+ int err;
+ socklen_t len = sizeof (err);
+
+ /* On Windows, the fourth parameter to getsockopt is a "char *";
+ on UNIX systems it is generally "void *". The cast to "char *"
+ is OK everywhere, since in C++ any data pointer type can be
+ implicitly converted to "void *". */
+ int ret = getsockopt (sock, SOL_SOCKET, SO_ERROR, (char *) &err, &len);
+
+ if (ret < 0)
+ {
+ int saved_errno = errno;
+
+ close (sock);
+ errno = saved_errno;
+ return -1;
+ }
+ else if (ret == 0 && err != 0)
+ {
+ close (sock);
+ errno = err;
+ return -1;
+ }
+
+ /* The connection succeeded. Return the socket. */
+ return sock;
+}
+
+/* Open a tcp socket. */
+
+int
+net_open (struct serial *scb, const char *name)
+{
+ struct addrinfo hint;
+ struct addrinfo *ainfo;
+
+ memset (&hint, 0, sizeof (hint));
+ /* Assume no prefix will be passed, therefore we should use
+ AF_UNSPEC. */
+ hint.ai_family = AF_UNSPEC;
+ hint.ai_socktype = SOCK_STREAM;
+ hint.ai_protocol = IPPROTO_TCP;
+
+ parsed_connection_spec parsed = parse_connection_spec (name, &hint);
+
+ if (parsed.port_str.empty ())
+ error (_("Missing port on hostname '%s'"), name);
+
+ int r = getaddrinfo (parsed.host_str.c_str (),
+ parsed.port_str.c_str (),
+ &hint, &ainfo);
+
+ if (r != 0)
+ {
+ fprintf_unfiltered (gdb_stderr, _("%s: cannot resolve name: %s\n"),
+ name, gai_strerror (r));
+ errno = ENOENT;
+ return -1;
+ }
+
+ scoped_free_addrinfo free_ainfo (ainfo);
+
+ /* Flag to indicate whether we've got a connection refused. It will
+ be true if any of the connections tried was refused. */
+ bool got_connrefused;
+ /* If a connection succeeds, SUCCESS_AINFO will point to the
+ 'struct addrinfo' that succeed. */
+ struct addrinfo *success_ainfo = NULL;
+ unsigned int polls = 0;
+
+ /* Assume the worst. */
+ scb->fd = -1;
+
+ do
+ {
+ got_connrefused = false;
+
+ for (addrinfo *iter = ainfo; iter != NULL; iter = iter->ai_next)
+ {
+ /* Iterate over the list of possible addresses to connect
+ to. For each, we'll try to connect and see if it
+ succeeds. */
+ int sock = try_connect (iter, &polls);
+
+ if (sock >= 0)
+ {
+ /* We've gotten a successful connection. Save its
+ 'struct addrinfo', the socket, and break. */
+ success_ainfo = iter;
+ scb->fd = sock;
+ break;
+ }
+ else if (
+#ifdef USE_WIN32API
+ errno == WSAECONNREFUSED
+#else
+ errno == ECONNREFUSED
+#endif
+ )
+ got_connrefused = true;
+ }
+ }
+ /* Just retry if:
+
+ - tcp_auto_retry is true, and
+ - We haven't gotten a connection yet, and
+ - Any of our connection attempts returned with ECONNREFUSED, and
+ - wait_for_connect signals that we can keep going. */
+ while (tcp_auto_retry
+ && success_ainfo == NULL
+ && got_connrefused
+ && wait_for_connect (-1, &polls) >= 0);
+
+ if (success_ainfo == NULL)
+ {
+ net_close (scb);
+ return -1;
+ }
+
+ /* Turn off nonblocking. */