On Mon, 8 Aug 2016, Philip Guenther wrote:
> On Mon, 8 Aug 2016, Todd C. Miller wrote:
> > POSIX says connect(2) does not restart so we need to do the same kind of 
> > dance as async connect(2).
> 
> Untested, but the obvious port from the other BSDs to have connect() leave 
> the connect running asynchronously.

Testing found a bug: returning EALREADY shouldn't be dependent on the 
socket being nonblocking.  Yay testing.

Second chunk the the tweak to the libpthread connect() test, overloading 
it to also check this case, as it was already exercising the "interrupt 
connect()" case.

ok?

Philip


Index: sys/kern/uipc_syscalls.c
===================================================================
RCS file: /data/src/openbsd/src/sys/kern/uipc_syscalls.c,v
retrieving revision 1.132
diff -u -p -r1.132 uipc_syscalls.c
--- sys/kern/uipc_syscalls.c    18 May 2016 01:13:13 -0000      1.132
+++ sys/kern/uipc_syscalls.c    9 Aug 2016 01:08:17 -0000
@@ -367,12 +367,12 @@ sys_connect(struct proc *p, void *v, reg
        struct file *fp;
        struct socket *so;
        struct mbuf *nam = NULL;
-       int error, s;
+       int error, s, interrupted = 0;
 
        if ((error = getsock(p, SCARG(uap, s), &fp)) != 0)
                return (error);
        so = fp->f_data;
-       if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) {
+       if (so->so_state & SS_ISCONNECTING) {
                FRELE(fp, p);
                return (EALREADY);
        }
@@ -409,8 +409,11 @@ sys_connect(struct proc *p, void *v, reg
        s = splsoftnet();
        while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) {
                error = tsleep(&so->so_timeo, PSOCK | PCATCH, "netcon2", 0);
-               if (error)
+               if (error) {
+                       if (error == EINTR || error == ERESTART)
+                               interrupted = 1;
                        break;
+               }
        }
        if (error == 0) {
                error = so->so_error;
@@ -418,7 +421,8 @@ sys_connect(struct proc *p, void *v, reg
        }
        splx(s);
 bad:
-       so->so_state &= ~SS_ISCONNECTING;
+       if (!interrupted)
+               so->so_state &= ~SS_ISCONNECTING;
        FRELE(fp, p);
        if (nam)
                m_freem(nam);
Index: regress/lib/libpthread/restart/connect/connect.c
===================================================================
RCS file: 
/data/src/openbsd/src/regress/lib/libpthread/restart/connect/connect.c,v
retrieving revision 1.1
diff -u -p -r1.1 connect.c
--- regress/lib/libpthread/restart/connect/connect.c    18 Sep 2011 16:36:58 
-0000      1.1
+++ regress/lib/libpthread/restart/connect/connect.c    9 Aug 2016 01:00:19 
-0000
@@ -30,7 +30,10 @@ thr_connect(void *arg)
        sa.sin_port = htons(23);
        sa.sin_addr.s_addr = htonl(0xc7b98903); /* cvs.openbsd.org */
        ASSERT(connect(s, (struct sockaddr *)&sa, sizeof(sa)) == -1);
-       return ((caddr_t)NULL + errno);
+       int err = errno;
+       ASSERT(connect(s, (struct sockaddr *)&sa, sizeof(sa)) == -1);
+       ASSERT(errno == EALREADY);
+       return ((caddr_t)NULL + err);
 }
 
 int

Reply via email to