From: Zdenek Dohnal Date: Thu, 14 Sep 2023 15:47:37 +0000 (+0200) Subject: cups/http-addrlist.c: Fix hanging on Solaris X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F788%2Fhead;p=thirdparty%2Fcups.git cups/http-addrlist.c: Fix hanging on Solaris Solaris behaves differently regarding connecting to a socket, so our current code caused hanging. The patch is from @l1gi's comment - https://github.com/OpenPrinting/cups/issues/156#issuecomment-1329212604 Fixes #156 --- diff --git a/CHANGES.md b/CHANGES.md index 4863110a19..b28f7a43cf 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -12,6 +12,7 @@ Changes in CUPS v2.5b1 (TBA) - Fixed delays in lpd backend (Issue #741) - Fixed extensive looping in scheduler (Issue #604) - Fixed hanging of `lpstat` on IBM AIX (Issue #773) +- Fixed hanging of `lpstat` on Solaris (Issue #156) - Fixed segfault in `cupsGetNamedDest()` when trying to get default printer, but the default printer is not set (Issue #719) - Fixed RFC 1179 port reserving behavior in LPD backend (Issue #743) diff --git a/cups/http-addrlist.c b/cups/http-addrlist.c index 81adfbcbf6..a0ee2f7667 100644 --- a/cups/http-addrlist.c +++ b/cups/http-addrlist.c @@ -288,6 +288,23 @@ httpAddrConnect2( for (i = 0; i < nfds; i ++) { DEBUG_printf("pfds[%d].revents=%x\n", i, pfds[i].revents); +# ifdef __sun + // Solaris connect runs asynchronously returning EINPROGRESS. Following + // poll() does not detect the socket is not connected and returns + // POLLIN|POLLOUT. Check the connection status and update error flag. + int sres, serr; + socklen_t slen = sizeof(serr); + sres = getsockopt(fds[i], SOL_SOCKET, SO_ERROR, &serr, &slen); + if (sres || serr) + { + pfds[i].revents |= POLLERR; +# ifdef DEBUG + DEBUG_printf(("1httpAddrConnect2: getsockopt returned: %d with error: %s", sres, strerror(serr))); +# endif + } +# endif // __sun + + if (pfds[i].revents && !(pfds[i].revents & (POLLERR | POLLHUP))) { *sock = fds[i]; @@ -303,18 +320,6 @@ httpAddrConnect2( } else if (pfds[i].revents & (POLLERR | POLLHUP)) { -# ifdef __sun - // Solaris incorrectly returns errors when you poll() a socket that is - // still connecting. This check prevents us from removing the socket - // from the pool if the "error" is EINPROGRESS... - int sockerr; // Current error on socket - socklen_t socklen = sizeof(sockerr); - // Size of error variable - - if (!getsockopt(fds[i], SOL_SOCKET, SO_ERROR, &sockerr, &socklen) && (!sockerr || sockerr == EINPROGRESS)) - continue; // Not an error -# endif // __sun - /* * Error on socket, remove from the "pool"... */