This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH][BZ #15362] Correctly return bytes written out in _IO_new_file_write


Hi,

In my fix to pr#11741 I was overzealous about forwarding a failed
write syscall and ignored an important case.
    
I overlooked the possibility of there having been a previous
successful partial write and hence returned a failure when it
shouldn't.  Attached patch causes _IO_new_file_write to return a short
write if such a situation occurs and return a complete failure only if
nothing was written to file in this function.

I also made an additional change in _IO_new_file_xsputn to explicitly
return failure if new_do_write returns a failure.  I had relied on an
ugly hack (n == to_do and adding 1 to to_do as a result of an error
results in n - to_do == -1, hence returning error), which is wrong.

Tested on x86_64 to verify that the fix works for the reproducer
mentioned in the bug report.  I have also verified that this patch
does not cause regressions in the testsuite.

OK to commit?

Siddhesh

	[BZ #15362]
	* libio/fileops.c (_IO_new_file_write): Correctly return short
	write.
	(_IO_new_file_xsputn): Explicitly return failure on write
	error.

diff --git a/libio/fileops.c b/libio/fileops.c
index 61b61b3..6ad0200 100644
--- a/libio/fileops.c
+++ b/libio/fileops.c
@@ -1263,7 +1263,17 @@ _IO_new_file_write (f, data, n)
   n -= to_do;
   if (f->_offset >= 0)
     f->_offset += n;
-  return count < 0 ? count : n;
+
+  /* The last syscall resulted in an error, but we did succeed in writing some
+     bits.  Send back a short write and let them try again if needed.  */
+  if (count < 0 && n > 0)
+    return n;
+
+  /* We didn't succeed in writing anything.  */
+  if (count < 0)
+    return count;
+
+  return n;
 }
 
 _IO_size_t
@@ -1336,6 +1346,10 @@ _IO_new_file_xsputn (f, data, n)
       if (do_write)
 	{
 	  count = new_do_write (f, s, do_write);
+
+	  if (count < 0)
+	    return count;
+
 	  to_do -= count;
 	  if (count < do_write)
 	    return n - to_do;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]