Date: Tue, 24 Sep 2002 11:23:19 -0400 (EDT) From: Andriy Gapon <avg@icyb.net.ua> To: FreeBSD-gnats-submit@FreeBSD.org Subject: standards/43335: libc_r: execve() and close-on-exec flag, interrupted write() Message-ID: <200209241523.g8OFNJp8081508@edge.foundation.invalid>
next in thread | raw e-mail | index | archive | help
>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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200209241523.g8OFNJp8081508>