This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: [PATCH v1.1][BZ #15362] Correctly return bytes written out in _IO_new_file_write
- From: Eric Biggers <ebiggers3 at gmail dot com>
- To: Siddhesh Poyarekar <siddhesh at redhat dot com>
- Cc: libc-alpha at sourceware dot org
- Date: Sat, 13 Apr 2013 17:53:48 -0500
- Subject: Re: [PATCH v1.1][BZ #15362] Correctly return bytes written out in _IO_new_file_write
- References: <20130412080539 dot GA9444 at spoyarek dot pnq dot redhat dot com> <20130412083331 dot GB9444 at spoyarek dot pnq dot redhat dot com> <20130413165247 dot GA10574 at zzz dot kirk dot macalester dot edu> <20130413172747 dot GA8146 at zzz dot kirk dot macalester dot edu>
> ... Another note: I changed the test condition
> in _IO_new_file_xsputn() to 'must_flush' instead of 'to_do == 0', which
> effectively makes the 0 return value apply without condition (3) in the 4
> conditions I listed above (i.e. 0 will now be returned if line-buffered data was
> partially buffered up to some newline character but could not be flushed). I
> think this is the correct behavior.
Upon further examination, testing 'must_flush' is exactly equivalent to testing
'to_do == 0', because the block of code is only entered if 'to_do + must_flush >
0'. Furthermore, 'must_flush' is only set if all the data to be written fits
into the internal buffer. So I believe that neither the original
_IO_new_file_xsputn() nor either version of the patched _IO_new_file_xsputn()
correctly handles the following sequence of events:
1. Data is written to a line-buffered FILE using fputs(), puts(), fwrite(), or
possibly other functions that internally call _IO_new_file_xsputn().
2. The amount of data to be written is greater than the space remaining in the
FILE's internal buffer, but there are one or more newlines in the part of
the data that does fit in the internal buffer.
3. The internal buffer is filled, but flushing it fails.
The current behavior in this situation is to return the number of bytes
buffered, which I believe would violate the meaning of "line-buffered" because
the code returns that it has successfully consumed data containing a newline
without having successfully flushed it out with the underlying write() system
call. Or am I misunderstanding how line buffering is supposed to work...? This
perhaps should be a separate bug, but this has to do with the very same line of
code.