From owner-freebsd-arch@FreeBSD.ORG Tue Jul 15 09:00:34 2003 Return-Path: Delivered-To: freebsd-arch@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id B094437B404 for ; Tue, 15 Jul 2003 09:00:34 -0700 (PDT) Received: from comp.chem.msu.su (comp-ext.chem.msu.su [158.250.32.157]) by mx1.FreeBSD.org (Postfix) with ESMTP id 0CA4843FA3 for ; Tue, 15 Jul 2003 09:00:31 -0700 (PDT) (envelope-from yar@comp.chem.msu.su) Received: from comp.chem.msu.su (localhost [127.0.0.1]) by comp.chem.msu.su (8.12.3p2/8.12.3) with ESMTP id h6FG0Pgb044336 for ; Tue, 15 Jul 2003 20:00:25 +0400 (MSD) (envelope-from yar@comp.chem.msu.su) Received: (from yar@localhost) by comp.chem.msu.su (8.12.3p2/8.12.3/Submit) id h6FG0P0F044332 for arch@freebsd.org; Tue, 15 Jul 2003 20:00:25 +0400 (MSD) (envelope-from yar) Date: Tue, 15 Jul 2003 20:00:25 +0400 From: Yar Tikhiy To: arch@freebsd.org Message-ID: <20030715160024.GA43108@comp.chem.msu.su> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.3i Subject: Interrupted connect(2) and errno issue X-BeenThere: freebsd-arch@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Discussion related to FreeBSD architecture List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 15 Jul 2003 16:00:35 -0000 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: %%%