On Sunday 11 March 2012 18:10, Rich Felker wrote:
> On Sun, Mar 11, 2012 at 04:12:19PM +0100, Denys Vlasenko wrote:
> > On Sunday 11 March 2012 14:46, Denys Vlasenko wrote:
> > > I propose the following patch.
> > > Only compile tested by me, care to run-test?
> > 
> > A more correct (I hope) version:
> 
> I'm curious why this is such a big patch introducing new functions and
> struct members. Couldn't it be just a one-line change in the function
> that writes out the buffers (i.e. do the buffer-voiding as soon as the
> error is hit rather than testing for it later)?

EINTR and EAGAIN should not result in output buffers being dropped.
You need to remember the error code for this.

> Perhaps I'm missing 
> something about uclibc's design that makes this not work well, but
> it's how my implementation in musl has always done it and I could
> switch to the bad glibc behavior just by changing one line...

How about this simpler one?


--- a/libc/stdio/_WRITE.c
+++ b/libc/stdio/_WRITE.c
@@ -58,13 +58,29 @@ size_t attribute_hidden __stdio_WRITE(register FILE *stream,
                        todo -= rv;
                        buf += rv;
                } else
-#ifdef __UCLIBC_MJN3_ONLY__
-#warning EINTR?
-#endif
-/*             if (errno != EINTR) */
-               {
-                       __STDIO_STREAM_SET_ERROR(stream);
 
+               __STDIO_STREAM_SET_ERROR(stream);
+
+               /* We buffer data on "transient" errors, but discard it
+                * on "hard" ones. Example of a hard error:
+                *
+                * close(fileno(stdout));
+                * printf("Hi there 1\n"); // EBADF
+                * dup2(good_fd, fileno(stdout));
+                * printf("Hi there 2\n"); // buffers new data
+                *
+                * This program should not print "Hi there 1" to good_fd.
+                * The rationale is that the caller of writing operation
+                * should check for error and act on it.
+                * If he didn't, then future users of the stream
+                * have no idea what to do.
+                * It's least confusing to at least not burden them with
+                * some hidden buffered crap in the buffer.
+                */
+               if (errno == EINTR
+                || errno == EAGAIN
+                /* do we have other "soft" errors? */
+               ) {
 #ifdef __STDIO_BUFFERS
                        stodo = __STDIO_STREAM_BUFFER_SIZE(stream);
                        if (stodo != 0) {
_______________________________________________
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc

Reply via email to