else { assert(addr->family == AF_INET6);
sa = (const struct sockaddr *)addr->ai->ai_addr; salen = addr->ai->ai_addrlen; break; case AF_INET6:
Socket sk_new(SockAddr addr, int port, int privport, int oobinline,	      int nodelay, Plug plug){    int s;#ifdef IPV6    struct sockaddr_in6 a6;#endif    struct sockaddr_in a;    int err;    Actual_Socket ret;    short localport;    int fl;    /*     * Create Socket structure.     */    ret = snew(struct Socket_tag);    ret->fn = &tcp_fn_table;    ret->error = NULL;    ret->plug = plug;    bufchain_init(&ret->output_data);    ret->connected = 0;		       /* to start with */    ret->writable = 0;		       /* to start with */    ret->sending_oob = 0;    ret->frozen = 0;    ret->frozen_readable = 0;    ret->localhost_only = 0;	       /* unused, but best init anyway */    ret->pending_error = 0;    ret->oobpending = FALSE;    ret->listener = 0;    /*     * Open socket.     */    assert(addr->family != AF_UNSPEC);    s = socket(addr->family, SOCK_STREAM, 0);    ret->s = s;    if (s < 0) {	ret->error = error_string(errno);	return (Socket) ret;    }    ret->oobinline = oobinline;    if (oobinline) {	int b = TRUE;	setsockopt(s, SOL_SOCKET, SO_OOBINLINE, (void *) &b, sizeof(b));    }    if (nodelay) {	int b = TRUE;	setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (void *) &b, sizeof(b));    }    /*     * Bind to local address.     */    if (privport)	localport = 1023;	       /* count from 1023 downwards */    else	localport = 0;		       /* just use port 0 (ie kernel picks) */    /* BSD IP stacks need sockaddr_in zeroed before filling in */    memset(&a,'\0',sizeof(struct sockaddr_in));#ifdef IPV6    memset(&a6,'\0',sizeof(struct sockaddr_in6));#endif    /* Loop round trying to bind */    while (1) {	int retcode;#ifdef IPV6	if (addr->family == AF_INET6) {	    /* XXX use getaddrinfo to get a local address? */	    a6.sin6_family = AF_INET6;	    a6.sin6_addr = in6addr_any;	    a6.sin6_port = htons(localport);	    retcode = bind(s, (struct sockaddr *) &a6, sizeof(a6));	} else#endif	{	    assert(addr->family == AF_INET);	    a.sin_family = AF_INET;	    a.sin_addr.s_addr = htonl(INADDR_ANY);	    a.sin_port = htons(localport);	    retcode = bind(s, (struct sockaddr *) &a, sizeof(a));	}	if (retcode >= 0) {	    err = 0;	    break;		       /* done */	} else {	    err = errno;	    if (err != EADDRINUSE)     /* failed, for a bad reason */		break;	}	if (localport == 0)	    break;		       /* we're only looping once */	localport--;	if (localport == 0)	    break;		       /* we might have got to the end */    }    if (err) {	ret->error = error_string(err);	return (Socket) ret;    }    /*     * Connect to remote address.     */#ifdef IPV6    /* XXX would be better to have got getaddrinfo() to fill in the port. */    if (addr->family == AF_INET)	((struct sockaddr_in *)addr->ai->ai_addr)->sin_port =	    htons(port);    else {	assert(addr->family == AF_INET6);	((struct sockaddr_in *)addr->ai->ai_addr)->sin_port =	    htons(port);    }#else    a.sin_family = AF_INET;    a.sin_addr.s_addr = htonl(addr->address);    a.sin_port = htons((short) port);#endif    fl = fcntl(s, F_GETFL);    if (fl != -1)	fcntl(s, F_SETFL, fl | O_NONBLOCK);    if ((#ifdef IPV6	    connect(s, addr->ai->ai_addr, addr->ai->ai_addrlen)#else	    connect(s, (struct sockaddr *) &a, sizeof(a))#endif	) < 0) {	if ( errno != EINPROGRESS ) {	    ret->error = error_string(errno);	    return (Socket) ret;	}    } else {	/*	 * If we _don't_ get EWOULDBLOCK, the connect has completed	 * and we should set the socket as connected and writable.	 */	ret->connected = 1;	ret->writable = 1;    }    uxsel_tell(ret);    add234(sktree, ret);    sk_addr_free(addr);    return (Socket) ret;}