diff options
author | Philip Guenther <guenther@cvs.openbsd.org> | 2016-08-09 02:25:36 +0000 |
---|---|---|
committer | Philip Guenther <guenther@cvs.openbsd.org> | 2016-08-09 02:25:36 +0000 |
commit | 76093549a56e2aed50d99915a84892f888cd1f34 (patch) | |
tree | fa1a6ae232f0e554f7455d1735e790f5d9673b4a | |
parent | df5c50b4de6fe61587aa6f1b73b69f8c84454cea (diff) |
When interrupted, connect() should leave the socket connecting in the
background, similar to a non-blocking socket. Return EALREADY whenever
already connecting, not just for non-blocking sockets. Fix from {Free,Net}BSD
Prompted by a report from Michael Reed (m.reed (at) mykolab.com)
ok millert@
-rw-r--r-- | regress/lib/libpthread/restart/connect/connect.c | 7 | ||||
-rw-r--r-- | sys/kern/uipc_syscalls.c | 14 |
2 files changed, 14 insertions, 7 deletions
diff --git a/regress/lib/libpthread/restart/connect/connect.c b/regress/lib/libpthread/restart/connect/connect.c index dfa62040a47..e1ef9ac2830 100644 --- a/regress/lib/libpthread/restart/connect/connect.c +++ b/regress/lib/libpthread/restart/connect/connect.c @@ -1,4 +1,4 @@ -/* $OpenBSD: connect.c,v 1.1 2011/09/18 16:36:58 fgsch Exp $ */ +/* $OpenBSD: connect.c,v 1.2 2016/08/09 02:25:35 guenther Exp $ */ /* * Federico G. Schwindt <fgsch@openbsd.org>, 2011. Public Domain. */ @@ -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 diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c index b00760dd939..a2505fe851b 100644 --- a/sys/kern/uipc_syscalls.c +++ b/sys/kern/uipc_syscalls.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uipc_syscalls.c,v 1.132 2016/05/18 01:13:13 millert Exp $ */ +/* $OpenBSD: uipc_syscalls.c,v 1.133 2016/08/09 02:25:35 guenther Exp $ */ /* $NetBSD: uipc_syscalls.c,v 1.19 1996/02/09 19:00:48 christos Exp $ */ /* @@ -367,12 +367,12 @@ sys_connect(struct proc *p, void *v, register_t *retval) 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, register_t *retval) 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, register_t *retval) } splx(s); bad: - so->so_state &= ~SS_ISCONNECTING; + if (!interrupted) + so->so_state &= ~SS_ISCONNECTING; FRELE(fp, p); if (nam) m_freem(nam); |