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