[summoning kre@] On Thu, Dec 12, 2024 at 13:58:06 -0600, J. Lewis Muir wrote:
> fgets() reads EOF right away, it does not append a NUL character. (I > confirmed this behavior on NetBSD 9.3 release.) I think it would be > helpful to clarify this in the man page. If it reads EOF right away, it returns NULL to indicate that no read has been performed, isn't it? When there's no read performed, why would it touch its argument it is supposed to read into? > I interpreted that to mean that it always appends a NUL character > regardless of why it stopped reading. But that's not what it does. It didn't stop reading, when you are at EOF, it didn't even start reading. > The FreeBSD fgets(3) man page > > https://man.freebsd.org/cgi/man.cgi?query=fgets&sektion=3 > > says the following, which I think is clearer and would have likely > helped me avoid my initial misunderstanding: > > Reading stops when a newline character is found, at end-of-file or > error. The newline, if any, is retained. If any characters are read > and there is no error, a `\0' character is appended to end the string. "...and there is no error..." is equally unclear to me. I'd venture a guess it means that if no reading was done b/c of an error, not that some reading was done and then there was an error. As written, the text above says (at least that's how I'd read it) that in the latter case there's no NUL appended. https://pubs.opengroup.org/onlinepubs/9799919799/functions/fgets.html POSIX is more clear: The fgets() function shall read bytes from stream into the array pointed to by s until n-1 bytes are read, or a <newline> is read and transferred to s, or an end-of-file condition is encountered. A null byte shall be written immediately after the last byte read into the array. If the end-of-file condition is encountered before any bytes are read, the contents of the array pointed to by s shall not be changed. RETURN VALUE Upon successful completion, fgets() shall return s. If the stream is at end-of-file, the end-of-file indicator for the stream shall be set and fgets() shall return a null pointer. If an error occurs, the error indicator for the stream shall be set, fgets() shall return a null pointer, and shall set errno to indicate the error. but the error case as written seems to demand that partial read interrupted by an error should return NULL, but the earlier text demands that the buffer (with partial data) should be NUL-terminated. It's not clear how a program should tell that partial read case apart from the failed read case. PS: Disclaimer: I didn't RTFS. -uwe