From owner-freebsd-standards Tue Sep 24 8:30:10 2002 Delivered-To: freebsd-standards@hub.freebsd.org Received: from mx1.FreeBSD.org (mx1.FreeBSD.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id ACFC637B401 for ; Tue, 24 Sep 2002 08:30:08 -0700 (PDT) Received: from freefall.freebsd.org (freefall.FreeBSD.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id 914C543E6E for ; Tue, 24 Sep 2002 08:30:07 -0700 (PDT) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.12.6/8.12.6) with ESMTP id g8OFU7Co028558 for ; Tue, 24 Sep 2002 08:30:07 -0700 (PDT) (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.12.6/8.12.6/Submit) id g8OFU7fh028557; Tue, 24 Sep 2002 08:30:07 -0700 (PDT) Received: from mx1.FreeBSD.org (mx1.FreeBSD.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 3174637B401 for ; Tue, 24 Sep 2002 08:23:22 -0700 (PDT) Received: from mta10.srv.hcvlny.cv.net (mta10.srv.hcvlny.cv.net [167.206.5.45]) by mx1.FreeBSD.org (Postfix) with ESMTP id 9442643E65 for ; Tue, 24 Sep 2002 08:23:21 -0700 (PDT) (envelope-from agapon@excite.com) Received: from edge.foundation.invalid (ool-182f9083.dyn.optonline.net [24.47.144.131]) by mta10.srv.hcvlny.cv.net (iPlanet Messaging Server 5.2 HotFix 0.9 (built Jul 29 2002)) with ESMTP id <0H2Y004WN82W3R@mta10.srv.hcvlny.cv.net> for FreeBSD-gnats-submit@freebsd.org; Tue, 24 Sep 2002 11:23:20 -0400 (EDT) Received: from edge.foundation.invalid (localhost.foundation.invalid [127.0.0.1]) by edge.foundation.invalid (8.12.3/8.12.3) with ESMTP id g8OFNJCZ081509 for ; Tue, 24 Sep 2002 11:23:19 -0400 Received: (from avg@localhost) by edge.foundation.invalid (8.12.3/8.12.3/Submit) id g8OFNJp8081508; Tue, 24 Sep 2002 11:23:19 -0400 (EDT) Message-Id: <200209241523.g8OFNJp8081508@edge.foundation.invalid> Date: Tue, 24 Sep 2002 11:23:19 -0400 (EDT) From: Andriy Gapon Reply-To: Andriy Gapon To: FreeBSD-gnats-submit@FreeBSD.org X-Send-Pr-Version: 3.113 Subject: standards/43335: libc_r: execve() and close-on-exec flag, interrupted write() Sender: owner-freebsd-standards@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG >Number: 43335 >Category: standards >Synopsis: libc_r: execve() and close-on-exec flag, interrupted write() >Confidential: no >Severity: serious >Priority: medium >Responsible: freebsd-standards >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Tue Sep 24 08:30:05 PDT 2002 >Closed-Date: >Last-Modified: >Originator: Andriy Gapon >Release: FreeBSD 4.6.2-RELEASE-p2 i386 >Organization: none >Environment: System: FreeBSD edge.foundation.invalid 4.6.2-RELEASE-p2 FreeBSD 4.6.2-RELEASE-p2 #5: Sat Sep 21 22:13:59 EDT 2002 avg@edge.foundation.invalid:/sys-devel/obj/sys-devel/src/sys/EDGE_ATAPICAM i386 >Description: 1. write() doesn't set errno to EINTR if thread receives a signal while being on a queue waiting for a data on a descriptor. 2. in the case above, write() always returns -1 regardless of wheather it was able to write part of data on previous attempts, I believe it should return number of bytes written thus far. 3. likewise, in the case "real" write() system call returns value < 0, libc_r write() retruns the same value, although some data might have been written on the previous attempts. 4. libc_r execve() sets all descriptors that were not set expicitely to non-blocking mode to blocking mode before doing "real" execve, which is good and done with non-multithreaded programs possibly being exec'ed in mind. However, it has a painful effect if this is done as part of spawning another process (fork+exec), obviously all descriptors in a parent become blocking that effectively kills multithreading during IO. I think there is no other option if a programmer really means to share descriptors between a multithreaded and a singlethreaded program. However, in the case close-on-exec flag is set on the descriptor, I think, it's better to leave the descriptor as is, in the non-blocking mode. >How-To-Repeat: sorry, that there is no test code, but for 1-3 possibility is obvious from the code. for 4, all you need to do is set close-on-exec flag on some descriptor that references for example a fifo, spawn a child process and see that if read from the fifo would block the whole process is blocked instead of a calling thread only. >Fix: see attached file >Release-Note: >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-standards" in the body of the message