]> git.ipfire.org Git - thirdparty/cups.git/commitdiff
cups/http-addrlist.c: Fix hanging on Solaris 788/head
authorZdenek Dohnal <zdohnal@redhat.com>
Thu, 14 Sep 2023 15:47:37 +0000 (17:47 +0200)
committerZdenek Dohnal <zdohnal@redhat.com>
Fri, 15 Sep 2023 05:58:39 +0000 (07:58 +0200)
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

CHANGES.md
cups/http-addrlist.c

index 4863110a197bc5493277dd19ef88820e56046ad0..b28f7a43cfc957a25a55d8832db675f81206d897 100644 (file)
@@ -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)
index 81adfbcbf6138eda1356a1c64c039961d6f76b46..a0ee2f76670f13e9a6b52350ca1ccf69748824f8 100644 (file)
@@ -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"...
           */