Skip site navigation (1)Skip section navigation (2)
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>