Red Hat Bugzilla – Bug 60028
write() on a full pipe blocks after select() claims the file descriptor is writable.
Last modified: 2007-04-18 12:40:28 EDT
From Bugzilla Helper:
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:0.9.8) Gecko/20020205
Description of problem:
When I have a full pipe, select() claims that the pipe's file descriptor is
writable, but a write() on the pipe blocks immediately. I'm pretty sure this
breaks POSIX compliance.
Version-Release number of selected component (if applicable):
kernel 2.4.9-21 errata for Red Hat Linux 7.2 (not verified with prior kernel revs).
Steps to Reproduce:
1. Install kernel 2.4.9-21 errata for Red Hat Linux 7.2
2. Compile the attached test program.
3. Run the test program under strace:
# strace testprogram
Actual Results: Output from strace:
dup2(4, 1) = 1
select(2, NULL, , NULL, NULL) = 1 (out )
write(1, "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"..., 8192
The process now remains blocked in the write syscall at this point, until the
process is killed.
Expected Results: I expect one of two POSIX compliant behaviors:
1) select() blocks until the pipe is not blocked, or:
2) select() indicates that the pipe is available for writing, but the subsequent
write() is only partially completed.
Created attachment 45940 [details]
Test program to reproduce this behavior.
I don't think it breaks SUSv3/POSIX compliance. From the standards document
"* If the O_NONBLOCK flag is clear, a write request may cause the thread to
block, but on normal completion it shall return nbytes"
On select it says:
"A descriptor shall be considered ready for writing when a call to an output
function with O_NONBLOCK clear would not block, whether or not the function
would transfer data successfully"
So once the pipe has at least one byte of room the select should say ready, and
a blocking 8K write should block.