From 997b28c2dc85583d8bf3630630b8f604afde32bd Mon Sep 17 00:00:00 2001 From: Zdenek Dohnal Date: Fri, 15 Sep 2023 09:42:03 +0200 Subject: [PATCH] cups/http-addrlist.c: Fix lpstat hanging on Solaris Fixes #156 --- CHANGES.md | 1 + cups/http-addrlist.c | 29 +++++++++++++++++------------ 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 5c5323d545..632e508210 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -8,6 +8,7 @@ Changes in CUPS v2.4.7 (TBA) - Fixed delays in lpd backend (Issue #741) - Fixed extensive logging in scheduler (Issue #604) - Fixed hanging of `lpstat` on IBM AIX (Issue #773) +- Fixed hanging of `lpstat` on Solaris (Issue #156) - Fixed printing to stderr if we can't open cups-files.conf (Issue #777) - Fixed purging job files via `cancel -x` (Issue #742) - Fixed RFC 1179 port reserving behavior in LPD backend (Issue #743) diff --git a/cups/http-addrlist.c b/cups/http-addrlist.c index 4fde80c5f7..198d073d06 100644 --- a/cups/http-addrlist.c +++ b/cups/http-addrlist.c @@ -318,6 +318,23 @@ httpAddrConnect2( { # ifdef HAVE_POLL 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))) # else if (FD_ISSET(fds[i], &input_set) && !FD_ISSET(fds[i], &error_set)) @@ -340,18 +357,6 @@ httpAddrConnect2( else if (FD_ISSET(fds[i], &error_set)) # endif /* HAVE_POLL */ { -# 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"... */ -- 2.47.2