Date: Tue, 15 Jul 2003 20:00:25 +0400 From: Yar Tikhiy <yar@freebsd.org> To: arch@freebsd.org Subject: Interrupted connect(2) and errno issue Message-ID: <20030715160024.GA43108@comp.chem.msu.su>
next in thread | raw e-mail | index | archive | help
Hi folks, Background: A blocking connect(2) call will be interrupted by any delivered signal, returning EINTR. Despites the call interrupted, the connection establishment will be carried out asynchronously, as though the socket were in non-blocking mode. The issue: Further calls to connect(2) on such a socket will return EADDRINUSE, while those on a non-blocking socket with connecting in progress will return EALREADY. Is there a reason for this difference? If there isn't, what do you think of the attached patch? I believe it will improve our conformance to POSIX. BTW, this patch could have been cleaner and not involved a new flag variable if we were able to drop the splx() stuff, which is anyway a no-op in CURRENT AFAIK. -- Yar --- uipc_syscalls.c.orig Thu Jun 19 07:55:01 2003 +++ uipc_syscalls.c Tue Jul 15 17:03:25 2003 @@ -480,11 +480,12 @@ { 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; } @@ -503,6 +504,8 @@ s = splnet(); while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) { error = tsleep(&so->so_timeo, PSOCK | PCATCH, "connec", 0); + if (error == EINTR || error == ERESTART) + interrupted = 1; if (error) break; } @@ -512,7 +515,8 @@ } splx(s); bad: - so->so_state &= ~SS_ISCONNECTING; + if (!interrupted) + so->so_state &= ~SS_ISCONNECTING; if (error == ERESTART) error = EINTR; done1: %%%
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20030715160024.GA43108>