* sendto_kdc.c (get_so_error): New function.
authorKen Raeburn <raeburn@mit.edu>
Mon, 22 Mar 2004 20:28:49 +0000 (20:28 +0000)
committerKen Raeburn <raeburn@mit.edu>
Mon, 22 Mar 2004 20:28:49 +0000 (20:28 +0000)
(service_tcp_fd): Call it for write fds as well as exception fds.

ticket: 2426
tags: pullup

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@16199 dc483132-0cff-0310-8789-dd5450dbe970

src/lib/krb5/os/ChangeLog
src/lib/krb5/os/sendto_kdc.c

index c175ae0300e7b4e79348d643946050dba956bc8c..7b2d330edb574d66cffb5b3f424964a81e96f229 100644 (file)
@@ -1,6 +1,8 @@
 2004-03-22  Ken Raeburn  <raeburn@mit.edu>
 
        * sendto_kdc.c (krb5int_sendto): Initialize select_state.end_time.
+       (get_so_error): New function.
+       (service_tcp_fd): Call it for write fds as well as exception fds.
 
 2004-03-18  Ezra Peisach  <epeisach@mit.edu>
 
index ba7b1c54a41a1bd41724db76928b39036c3c5f35..3f8eb777f135e41418da6889d7dde5819a91dce0 100644 (file)
@@ -707,6 +707,25 @@ kill_conn(struct conn_state *conn, struct select_state *selstate, int err)
     selstate->nfds--;
 }
 
+/* Check socket for error.  */
+static int
+get_so_error(int fd)
+{
+    int e, sockerr;
+    socklen_t sockerrlen;
+
+    sockerr = 0;
+    sockerrlen = sizeof(sockerr);
+    e = getsockopt(fd, SOL_SOCKET, SO_ERROR, &sockerr, &sockerrlen);
+    if (e != 0) {
+       /* What to do now?  */
+       e = SOCKET_ERRNO;
+       dprint("getsockopt(SO_ERROR) on fd failed: %m\n", e);
+       return e;
+    }
+    return sockerr;
+}
+
 /* Return nonzero only if we're finished and the caller should exit
    its loop.  This happens in two cases: We have a complete message,
    or the socket has closed and no others are open.  */
@@ -736,35 +755,29 @@ service_tcp_fd (struct conn_state *conn, struct select_state *selstate,
            return e == 0;
        }
        if (ssflags & SSF_EXCEPTION) {
-#ifdef DEBUG
-           int sockerr;
-           socklen_t sockerrlen;
-#endif
        handle_exception:
-#ifdef DEBUG
-           sockerrlen = sizeof(sockerr);
-           e = getsockopt(conn->fd, SOL_SOCKET, SO_ERROR,
-                          &sockerr, &sockerrlen);
-           if (e != 0) {
-               /* What to do now?  */
-               e = SOCKET_ERRNO;
-               dprint("getsockopt(SO_ERROR) on exception fd failed: %m\n", e);
-               goto kill_conn;
-           }
-           /* Okay, got the error back.  Either way, kill the
-              connection.  */
-           e = sockerr;
-#else
-           e = 1;              /* need only be non-zero */
-#endif
+           e = get_so_error(conn->fd);
+           if (e)
+               dprint("socket error on exception fd: %m", e);
+           else
+               dprint("no socket error info available on exception fd");
            goto kill_conn;
        }
 
        /*
         * Connect finished -- but did it succeed or fail?
         * UNIX sets can_write if failed.
-        * Try writing, I guess, and find out.
+        * Call getsockopt to see if error pending.
+        *
+        * (For most UNIX systems it works to just try writing the
+        * first time and detect an error.  But Bill Dodd at IBM
+        * reports that some version of AIX, SIGPIPE can result.)
         */
+       e = get_so_error(conn->fd);
+       if (e) {
+           dprint("socket error on write fd: %m", e);
+           goto kill_conn;
+       }
        conn->state = WRITING;
        goto try_writing;