Bug 5156

Summary: fclose and fflush do not report write failures
Product: uClibc Reporter: Michael Deutschmann <michael>
Component: stdioAssignee: unassigned
Status: NEW ---    
Severity: major CC: stefan.tauner, uclibc-cvs
Priority: P5    
Version: 0.9.33.1   
Target Milestone: ---   
Hardware: PC   
OS: Linux   
Host: Target:
Build:
Attachments: Testcase for failure to report fclose/fflush failure

Description Michael Deutschmann 2012-04-29 05:30:56 UTC
Created attachment 4310 [details]
Testcase for failure to report fclose/fflush failure

The fclose() and fflush() functions do not return EOF when buffered information could not be written out.

This causes spurious test failures on modern GNU utilities (their testsuites enforce that "foo --version > /dev/full" returns a failure exit status).

I'm attaching a simple testcase program containing two variations, both of which 0.9.33.1 fails.
Comment 1 Leonid 2012-04-30 09:40:02 UTC
Proposed fix:

--- a/libc/stdio/_wcommit.c
+++ b/libc/stdio/_wcommit.c
@@ -23,6 +23,8 @@ size_t attribute_hidden __stdio_wcommit(
 	if ((bufsize = __STDIO_STREAM_BUFFER_WUSED(stream)) != 0) {
 		stream->__bufpos = stream->__bufstart;
 		__stdio_WRITE(stream, stream->__bufstart, bufsize);
+		if (stream->__modeflags & __FLAG_ERROR)
+			return bufsize;
 	}
 
 	return __STDIO_STREAM_BUFFER_WUSED(stream);
Comment 2 stefanct 2015-11-22 15:46:56 UTC
This (together with the fact that fwrite() reports to succeed in writing the requested number of bytes) causes real world applications to fail to even notice that there is a problem and produce corrupt user data.

My test case is writing a regular file to a full vfat file system on Linux. MUSL and glibc report the problem already at fwrite() time while uclibc does not report any problem in fwrite() nor fclose(). This is a disastrous bug.