shwaresyst@aol.com <shwaresyst@aol.com> wrote, on 03 Nov 2009:
>
> Could be less a bug in the example than the wording of the function's
> behavior. Taking the function description literally, you do have a case
> that there's a discrepancy. Taking the example as an expression of the
> intent of the description, though, it could be interpreted that up to
> n-1 characters will be read that aren't newline chars by an
> implementation and if it gets that far the nth char is to be assumed to
> be a newline, as the function is intended for use with well formed text
> streams that would have honored the LINE_MAX length when created.
The problem with the example is worse than that. It uses the value of
the LINE_MAX macro from <limits.h>. This is not necessarily equal to
the true {LINE_MAX} limit. (It is a "runtime increasable" value.)
Therefore, even if the input lines honour {LINE_MAX}, they could have
lengths exceeding the value of the LINE_MAX macro.
> As the
> stream can be any type of file, though, this assumption can't be
> guaranteed and the description is erroneously silent on whether the nth
> char explicitly should or shouldn't be validated as being that newline,
> and copied to the buffer if so, or is it a malformed line and that nth
> char should also be copied but with just the trailing null, or should a
> newline char be explicitly appended as char n and then the null, with
> the actual nth char left as the next char to be read or is it thrown
> away.
I think the intention is that the example shows how to read lines
from a text file. So it doesn't need to deal with "lines" longer
than {LINE_MAX} (except perhaps to report them as an error). The
code could be fixed by obtaining the true {LINE_MAX} value from
sysconf() and allocating a buffer of {LINE_MAX}+1 bytes. The
introductory paragraph would also need changing.
> The description also does not specify the behavior when nulls are read
> from the file. Copying these could lead an application to believe that
> end-of-file was reached also if the preceding character is anything other
> than a newline.
The description says what fgets() does with bytes read from the
stream. This description applies to null bytes just the same as
other bytes, since there is no exception stated for null bytes.
However, there does appear to be a wording problem with the
statement:
"The string is then terminated with a null byte."
If a null byte was read from the stream, then the null added by
fgets() will not terminate the string.
The C Standard words it differently:
"A null character is written immediately after the last character
read into the array."
It is careful not to say that this added null character (byte in POSIX
terminology) terminates the string. In POSIX we should change:
"The string is then terminated with a null byte."
to
"A null byte shall be written immediately after the last byte
read into the array."
> As such, the scope of the fgets() description appears to be deficient.
> I'm open to suggestion on whether an aardvark report or interpretation
> request is most suitable to address these, or should this be reported to
> the C working group since the description defers to the C standard.
An aardvark is needed to fix the null byte problem and the example.
--
Geoff Clare <g.clare@opengroup.org>
The Open Group, Thames Tower, Station Road, Reading, RG1 1LX, England
|