Bring following change from FreeBSD (yar@freebsd.org):
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Sat, 26 Jul 2008 15:36:28 +0000 (15:36 +0000)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Sat, 26 Jul 2008 15:36:28 +0000 (15:36 +0000)
  uipc_syscall.c rev 1.154

  If connect(2) has been interrupted by a signal and therefore the
  connection is to be established asynchronously, behave as in the
  case of non-blocking mode:

  - keep the SS_ISCONNECTING bit set thus indicating that
    the connection establishment is in progress, which is the case
    (clearing the bit in this case was just a bug);

  - return EALREADY, instead of the confusing and unreasonable
    EADDRINUSE, upon further connect(2) attempts on this socket
    until the connection is established (this also brings our
    connect(2) into accord with IEEE Std 1003.1.)

Tested-by: y0netan1@
Reviewed-by: hsu@
Dragonfly-bug: <http://bugs.dragonflybsd.org/issue1079>

sys/kern/uipc_syscalls.c

index c54a406..a9f0fb4 100644 (file)
@@ -35,7 +35,7 @@
  *
  *     @(#)uipc_syscalls.c     8.4 (Berkeley) 2/21/94
  * $FreeBSD: src/sys/kern/uipc_syscalls.c,v 1.65.2.17 2003/04/04 17:11:16 tegge Exp $
- * $DragonFly: src/sys/kern/uipc_syscalls.c,v 1.88 2008/07/10 00:19:27 aggelos Exp $
+ * $DragonFly: src/sys/kern/uipc_syscalls.c,v 1.89 2008/07/26 15:36:28 sephe Exp $
  */
 
 #include "opt_ktrace.h"
@@ -453,7 +453,7 @@ kern_connect(int s, int fflags, struct sockaddr *sa)
        struct proc *p = td->td_proc;
        struct file *fp;
        struct socket *so;
-       int error;
+       int error, interrupted = 0;
 
        error = holdsock(p->p_fd, s, &fp);
        if (error)
@@ -467,7 +467,7 @@ kern_connect(int s, int fflags, struct sockaddr *sa)
        else
                fflags = fp->f_flag;
 
-       if ((fflags & FNONBLOCK) && (so->so_state & SS_ISCONNECTING)) {
+       if (so->so_state & SS_ISCONNECTING) {
                error = EALREADY;
                goto done;
        }
@@ -492,13 +492,16 @@ kern_connect(int s, int fflags, struct sockaddr *sa)
                msg.nm_so = so;
                msg.nm_etype = NM_REVENT;
                error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, PCATCH);
+               if (error == EINTR || error == ERESTART)
+                       interrupted = 1;
        }
        if (error == 0) {
                error = so->so_error;
                so->so_error = 0;
        }
 bad:
-       so->so_state &= ~SS_ISCONNECTING;
+       if (!interrupted)
+               so->so_state &= ~SS_ISCONNECTING;
        if (error == ERESTART)
                error = EINTR;
 done: