about summary refs log tree commit diff
path: root/src/stdio/__toread.c
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2015-05-28 23:08:12 -0400
committerRich Felker <dalias@aerifal.cx>2015-05-29 00:04:36 -0400
commit2b4fcfdacf93c3dfd6ac15e31790a9e154374679 (patch)
treeb4f112b30707d9772dfa8b61e9cfec870c690b46 /src/stdio/__toread.c
parentb6e7c664677ab7c77f183b8c41105f2be519800c (diff)
downloadmusl-2b4fcfdacf93c3dfd6ac15e31790a9e154374679.tar.gz
musl-2b4fcfdacf93c3dfd6ac15e31790a9e154374679.tar.xz
musl-2b4fcfdacf93c3dfd6ac15e31790a9e154374679.zip
fix failure of ungetc and ungetwc to work on files in eof status
these functions were written to handle clearing eof status, but failed
to account for the __toread function's handling of eof. with this
patch applied, __toread still returns EOF when the file is in eof
status, so that read operations will fail, but it also sets up valid
buffer pointers for read mode, which are set to the end of the buffer
rather than the beginning in order to make the whole buffer available
to ungetc/ungetwc.

minor changes to __uflow were needed since it's now possible to have
non-zero buffer pointers while in eof status. as made, these changes
remove a 'fast path' bypassing the function call to __toread, which
could be reintroduced with slightly different logic, but since
ordinary files have a syscall in f->read, optimizing the code path
does not seem worthwhile.

the __stdio_read function is also updated not to zero the read buffer
pointers on eof/error. while not necessary for correctness, this
change avoids the overhead of calling __toread in ungetc after
reaching eof, and it also reduces code size and increases consistency
with the fmemopen read operation which does not zero the pointers.
Diffstat (limited to 'src/stdio/__toread.c')
-rw-r--r--src/stdio/__toread.c8
1 files changed, 4 insertions, 4 deletions
diff --git a/src/stdio/__toread.c b/src/stdio/__toread.c
index 52624f3d..b08f5bb4 100644
--- a/src/stdio/__toread.c
+++ b/src/stdio/__toread.c
@@ -5,12 +5,12 @@ int __toread(FILE *f)
 	f->mode |= f->mode-1;
 	if (f->wpos > f->buf) f->write(f, 0, 0);
 	f->wpos = f->wbase = f->wend = 0;
-	if (f->flags & (F_EOF|F_NORD)) {
-		if (f->flags & F_NORD) f->flags |= F_ERR;
+	if (f->flags & F_NORD) {
+		f->flags |= F_ERR;
 		return EOF;
 	}
-	f->rpos = f->rend = f->buf;
-	return 0;
+	f->rpos = f->rend = f->buf + f->buf_size;
+	return (f->flags & F_EOF) ? EOF : 0;
 }
 
 void __stdio_exit_needed(void);