diff options
author | msweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be> | 2012-02-13 16:35:48 +0000 |
---|---|---|
committer | msweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be> | 2012-02-13 16:35:48 +0000 |
commit | 12f89d241ce15358fb71ef1b1249803ee9d97374 (patch) | |
tree | e4d30c1cef3c83b1f816ce482592c96a21daa4b3 /cups/http-addrlist.c | |
parent | dcb445bcf3e9ec2efd56550263052aca70beb08e (diff) | |
download | cups-12f89d241ce15358fb71ef1b1249803ee9d97374.tar.gz |
Merge changes from CUPS 1.6svn-r10267.
git-svn-id: svn+ssh://src.apple.com/svn/cups/easysw/current@3643 a1ca3aef-8c08-0410-bb20-df032aa958be
Diffstat (limited to 'cups/http-addrlist.c')
-rw-r--r-- | cups/http-addrlist.c | 100 |
1 files changed, 64 insertions, 36 deletions
diff --git a/cups/http-addrlist.c b/cups/http-addrlist.c index 4e1a423b7..e6ea4eb62 100644 --- a/cups/http-addrlist.c +++ b/cups/http-addrlist.c @@ -68,17 +68,18 @@ httpAddrConnect2( int val; /* Socket option value */ #ifdef O_NONBLOCK socklen_t len; /* Length of value */ + http_addr_t peer; /* Peer address */ int flags, /* Socket flags */ remaining; /* Remaining timeout */ -#endif /* O_NONBLOCK */ -#ifdef HAVE_POLL +# ifdef HAVE_POLL struct pollfd pfd; /* Polled file descriptor */ -#else +# else fd_set input_set, /* select() input set */ output_set; /* select() output set */ struct timeval timeout; /* Timeout */ -#endif /* HAVE_POLL */ +# endif /* HAVE_POLL */ int nfds; /* Result from select()/poll() */ +#endif /* O_NONBLOCK */ #ifdef DEBUG char temp[256]; /* Temporary address string */ #endif /* DEBUG */ @@ -97,7 +98,7 @@ httpAddrConnect2( if (cancel && *cancel) return (NULL); - if (msec <= 0) + if (msec <= 0 || getenv("CUPS_DISABLE_ASYNC_CONNECT")) msec = INT_MAX; /* @@ -106,11 +107,14 @@ httpAddrConnect2( while (addrlist) { + if (cancel && *cancel) + return (NULL); + /* * Create the socket... */ - DEBUG_printf(("2httpAddrConnect: Trying %s:%d...", + DEBUG_printf(("2httpAddrConnect2: Trying %s:%d...", httpAddrString(&(addrlist->addr), temp, sizeof(temp)), _httpAddrPort(&(addrlist->addr)))); @@ -175,8 +179,12 @@ httpAddrConnect2( */ flags = fcntl(*sock, F_GETFL, 0); - if (msec > 0) + if (msec != INT_MAX) + { + DEBUG_puts("httpAddrConnect2: Setting non-blocking connect()"); + fcntl(*sock, F_SETFL, flags | O_NONBLOCK); + } #endif /* O_NONBLOCK */ /* @@ -186,7 +194,7 @@ httpAddrConnect2( if (!connect(*sock, &(addrlist->addr.addr), httpAddrLength(&(addrlist->addr)))) { - DEBUG_printf(("1httpAddrConnect: Connected to %s:%d...", + DEBUG_printf(("1httpAddrConnect2: Connected to %s:%d...", httpAddrString(&(addrlist->addr), temp, sizeof(temp)), _httpAddrPort(&(addrlist->addr)))); @@ -199,40 +207,49 @@ httpAddrConnect2( #ifdef O_NONBLOCK # ifdef WIN32 - if (errno == WSAEINPROGRESS) + if (WSAGetLastError() == WSAEINPROGRESS || + WSAGetLastError() == WSAEWOULDBLOCK) # else - if (errno == EINPROGRESS) + if (errno == EINPROGRESS || errno == EWOULDBLOCK) # endif /* WIN32 */ { - for (remaining = msec; remaining > 0; remaining -= 250) - { -# ifdef HAVE_POLL - pfd.fd = *sock; - pfd.events = POLLIN | POLLOUT; + DEBUG_puts("1httpAddrConnect2: Finishing async connect()"); - while ((nfds = poll(&pfd, 1, remaining > 250 ? 250 : remaining)) < 0 && - (errno == EINTR || errno == EAGAIN)); + fcntl(*sock, F_SETFL, flags); -# else + for (remaining = msec; remaining > 0; remaining -= 250) + { do - { - if (cancel && *cancel) - { + { + if (cancel && *cancel) + { /* * Close this socket and return... */ -#ifdef WIN32 + DEBUG_puts("1httpAddrConnect2: Canceled connect()"); + +# ifdef WIN32 closesocket(*sock); -#else +# else close(*sock); -#endif /* WIN32 */ +# endif /* WIN32 */ *sock = -1; return (NULL); - } + } +# ifdef HAVE_POLL + pfd.fd = *sock; + pfd.events = POLLIN | POLLOUT; + + nfds = poll(&pfd, 1, remaining > 250 ? 250 : remaining); + + DEBUG_printf(("1httpAddrConnect2: poll() returned %d (%d)", nfds, + errno)); + +# else FD_ZERO(&input_set); FD_SET(*sock, &input_set); output_set = input_set; @@ -241,25 +258,27 @@ httpAddrConnect2( timeout.tv_usec = (remaining > 250 ? 250 : remaining) * 1000; nfds = select(*sock + 1, &input_set, &output_set, NULL, &timeout); + + DEBUG_printf(("1httpAddrConnect2: select() returned %d (%d)", nfds, + errno)); +# endif /* HAVE_POLL */ } -# ifdef WIN32 +# ifdef WIN32 while (nfds < 0 && (WSAGetLastError() == WSAEINTR || WSAGetLastError() == WSAEWOULDBLOCK)); -# else +# else while (nfds < 0 && (errno == EINTR || errno == EAGAIN)); -# endif /* WIN32 */ -# endif /* HAVE_POLL */ +# endif /* WIN32 */ if (nfds > 0) { - len = sizeof(val); - if (getsockopt(*sock, SOL_SOCKET, SO_ERROR, &val, &len) >= 0) + len = sizeof(peer); + if (!getpeername(*sock, (struct sockaddr *)&peer, &len)) { - DEBUG_printf(("1httpAddrConnect: Connected to %s:%d...", - httpAddrString(&(addrlist->addr), temp, sizeof(temp)), - _httpAddrPort(&(addrlist->addr)))); + DEBUG_printf(("1httpAddrConnect2: Connected to %s:%d...", + httpAddrString(&peer, temp, sizeof(temp)), + _httpAddrPort(&peer))); - fcntl(*sock, F_SETFL, flags); return (addrlist); } @@ -269,10 +288,15 @@ httpAddrConnect2( } #endif /* O_NONBLOCK */ - DEBUG_printf(("1httpAddrConnect: Unable to connect to %s:%d: %s", + DEBUG_printf(("1httpAddrConnect2: Unable to connect to %s:%d: %s", httpAddrString(&(addrlist->addr), temp, sizeof(temp)), _httpAddrPort(&(addrlist->addr)), strerror(errno))); +#ifndef WIN32 + if (errno == EINPROGRESS) + errno = ETIMEDOUT; +#endif /* !WIN32 */ + /* * Close this socket and move to the next address... */ @@ -288,7 +312,11 @@ httpAddrConnect2( } if (!addrlist) +#ifdef WIN32 + _cupsSetError(IPP_SERVICE_UNAVAILABLE, "Connection failed", 0); +#else _cupsSetError(IPP_SERVICE_UNAVAILABLE, strerror(errno), 0); +#endif /* WIN32 */ return (addrlist); } |