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.)
This commit is contained in:
Yaroslav Tykhiy 2003-08-06 14:04:47 +00:00
parent 9a6d13bede
commit b81694ed13

View File

@ -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: