summaryrefslogtreecommitdiff
path: root/cups/http-addrlist.c
diff options
context:
space:
mode:
authormsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>2012-02-13 16:35:48 +0000
committermsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>2012-02-13 16:35:48 +0000
commit12f89d241ce15358fb71ef1b1249803ee9d97374 (patch)
treee4d30c1cef3c83b1f816ce482592c96a21daa4b3 /cups/http-addrlist.c
parentdcb445bcf3e9ec2efd56550263052aca70beb08e (diff)
downloadcups-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.c100
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);
}