summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoryar <yar@FreeBSD.org>2003-08-06 14:04:47 +0000
committeryar <yar@FreeBSD.org>2003-08-06 14:04:47 +0000
commit65e49017604fba0d060a6a3b9a3c8e9ec05f91b0 (patch)
treec041eaf1fc56671f74891e33d081aa2495e5b520
parent4af00ec0ba74014550bd3c1ab9baa19ad3aae7d2 (diff)
downloadFreeBSD-src-65e49017604fba0d060a6a3b9a3c8e9ec05f91b0.zip
FreeBSD-src-65e49017604fba0d060a6a3b9a3c8e9ec05f91b0.tar.gz
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.)
-rw-r--r--sys/kern/uipc_syscalls.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c
index 9bd2638..e6f4076 100644
--- a/sys/kern/uipc_syscalls.c
+++ b/sys/kern/uipc_syscalls.c
@@ -481,11 +481,12 @@ kern_connect(td, fd, sa)
{
struct socket *so;
int error, s;
+ int interrupted = 0;
mtx_lock(&Giant);
if ((error = fgetsock(td, fd, &so, NULL)) != 0)
goto done2;
- if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) {
+ if (so->so_state & SS_ISCONNECTING) {
error = EALREADY;
goto done1;
}
@@ -504,8 +505,11 @@ kern_connect(td, fd, sa)
s = splnet();
while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) {
error = tsleep(&so->so_timeo, PSOCK | PCATCH, "connec", 0);
- if (error)
+ if (error) {
+ if (error == EINTR || error == ERESTART)
+ interrupted = 1;
break;
+ }
}
if (error == 0) {
error = so->so_error;
@@ -513,7 +517,8 @@ kern_connect(td, fd, sa)
}
splx(s);
bad:
- so->so_state &= ~SS_ISCONNECTING;
+ if (!interrupted)
+ so->so_state &= ~SS_ISCONNECTING;
if (error == ERESTART)
error = EINTR;
done1:
OpenPOWER on IntegriCloud