mailing list of musl libc
 help / color / mirror / code / Atom feed
* fgets behaviour after eof
@ 2014-08-27 11:16 Szabolcs Nagy
  2014-08-27 16:52 ` Rich Felker
  2014-08-27 17:14 ` Rich Felker
  0 siblings, 2 replies; 3+ messages in thread
From: Szabolcs Nagy @ 2014-08-27 11:16 UTC (permalink / raw)
  To: musl

the C standard requires that

"If end-of-file is encountered and no characters have been read into the
array, the contents of the array remain unchanged and a null pointer is
returned. If a read error occurs during the operation, the array contents
are indeterminate and a null pointer is returned."

but musl's fgets always terminates the buffer with \0 even after EOF,
this is easy to fix:

-       *p = 0;
+       if (s) *p = 0;

However the behaviour of fgets(s, 1, f) is unclear if feof(f) is true,
in this case nothing is read so fgets cannot "encounter" end-of-file,
so it may set s[0]=0 and return s or it could check feof and return 0.
(glibc does not check feof)


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: fgets behaviour after eof
  2014-08-27 11:16 fgets behaviour after eof Szabolcs Nagy
@ 2014-08-27 16:52 ` Rich Felker
  2014-08-27 17:14 ` Rich Felker
  1 sibling, 0 replies; 3+ messages in thread
From: Rich Felker @ 2014-08-27 16:52 UTC (permalink / raw)
  To: musl

On Wed, Aug 27, 2014 at 01:16:20PM +0200, Szabolcs Nagy wrote:
> the C standard requires that
> 
> "If end-of-file is encountered and no characters have been read into the
> array, the contents of the array remain unchanged and a null pointer is
> returned. If a read error occurs during the operation, the array contents
> are indeterminate and a null pointer is returned."
> 
> but musl's fgets always terminates the buffer with \0 even after EOF,
> this is easy to fix:
> 
> -       *p = 0;
> +       if (s) *p = 0;

This is wrong and should be fixed, yes.

> However the behaviour of fgets(s, 1, f) is unclear if feof(f) is true,
> in this case nothing is read so fgets cannot "encounter" end-of-file,
> so it may set s[0]=0 and return s or it could check feof and return 0.
> (glibc does not check feof)

This is a known WONTFIX bug in glibc from the Drepper era. Remember,
all stdio read operations are defined in terms of fgetc, for which it
is specified:

"Upon successful completion, fgetc() shall return the next byte from
the input stream pointed to by stream. If the end-of-file indicator
                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
for the stream is set, or if the stream is at end-of-file, the
^^^^^^^^^^^^^^^^^^^^^
end-of-file indicator for the stream shall be set and fgetc() shall
return EOF."

Thus, fgets encounters EOF from fgetc.

Rich


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: fgets behaviour after eof
  2014-08-27 11:16 fgets behaviour after eof Szabolcs Nagy
  2014-08-27 16:52 ` Rich Felker
@ 2014-08-27 17:14 ` Rich Felker
  1 sibling, 0 replies; 3+ messages in thread
From: Rich Felker @ 2014-08-27 17:14 UTC (permalink / raw)
  To: musl

On Wed, Aug 27, 2014 at 01:16:20PM +0200, Szabolcs Nagy wrote:
> However the behaviour of fgets(s, 1, f) is unclear if feof(f) is true,
> in this case nothing is read so fgets cannot "encounter" end-of-file,
> so it may set s[0]=0 and return s or it could check feof and return 0.
> (glibc does not check feof)

Sorry, I missed the fact n==1. In this case, no read ever occurs (0
bytes have already been read) so the following text simply applies:

"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. The
string is then terminated with a null byte."

and of course:

"Upon successful completion, fgets() shall return s."

This is all handled correctly in the special case at the top of the
function. The only thing that may be incorrect is the failure to wait
on the file lock in this case; formally, all operations on FILE are
supposed to obtain the lock, and presumably fgets(f, 1, &(char){0})
could be a sort of 'barrier' to "wait until thread with lock on f has
unlocked it".

Your other correction at the end of the function, when EOF or error
was seen, still applies though.

Rich


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2014-08-27 17:14 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-08-27 11:16 fgets behaviour after eof Szabolcs Nagy
2014-08-27 16:52 ` Rich Felker
2014-08-27 17:14 ` Rich Felker

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/musl/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).