about summary refs log tree commit diff
path: root/libio/fileops.c
diff options
context:
space:
mode:
authorSiddhesh Poyarekar <siddhesh@redhat.com>2012-11-16 19:13:11 +0530
committerSiddhesh Poyarekar <siddhesh@redhat.com>2012-11-16 19:13:11 +0530
commit2b766585f9b4ffabeef2f36200c275976b93f2c7 (patch)
treed6be89abc6bfa88e5e9fd997bb4cfd94b035adc2 /libio/fileops.c
parentb1848fdeec705bc7d2f64e3a365f1ff66eeb4f0d (diff)
downloadglibc-2b766585f9b4ffabeef2f36200c275976b93f2c7.tar.gz
glibc-2b766585f9b4ffabeef2f36200c275976b93f2c7.tar.xz
glibc-2b766585f9b4ffabeef2f36200c275976b93f2c7.zip
printf should return negative value on error
[BZ #11741]
Fixed bug where printf and family may return a spurious success when
printing padded formats.
Diffstat (limited to 'libio/fileops.c')
-rw-r--r--libio/fileops.c18
1 files changed, 10 insertions, 8 deletions
diff --git a/libio/fileops.c b/libio/fileops.c
index 6aabadc644..fb6ac17b64 100644
--- a/libio/fileops.c
+++ b/libio/fileops.c
@@ -1253,12 +1253,13 @@ _IO_new_file_write (f, data, n)
      _IO_ssize_t n;
 {
   _IO_ssize_t to_do = n;
+  _IO_ssize_t count = 0;
   while (to_do > 0)
     {
-      _IO_ssize_t count = (__builtin_expect (f->_flags2
-					     & _IO_FLAGS2_NOTCANCEL, 0)
-			   ? write_not_cancel (f->_fileno, data, to_do)
-			   : write (f->_fileno, data, to_do));
+      count = (__builtin_expect (f->_flags2
+				 & _IO_FLAGS2_NOTCANCEL, 0)
+	       ? write_not_cancel (f->_fileno, data, to_do)
+	       : write (f->_fileno, data, to_do));
       if (count < 0)
 	{
 	  f->_flags |= _IO_ERR_SEEN;
@@ -1270,7 +1271,7 @@ _IO_new_file_write (f, data, n)
   n -= to_do;
   if (f->_offset >= 0)
     f->_offset += n;
-  return n;
+  return count < 0 ? count : n;
 }
 
 _IO_size_t
@@ -1330,9 +1331,10 @@ _IO_new_file_xsputn (f, data, n)
       _IO_size_t block_size, do_write;
       /* Next flush the (full) buffer. */
       if (_IO_OVERFLOW (f, EOF) == EOF)
-	/* If nothing else has to be written we must not signal the
-	   caller that everything has been written.  */
-	return to_do == 0 ? EOF : n - to_do;
+	/* If nothing else has to be written or nothing has been written, we
+	   must not signal the caller that the call was even partially
+	   successful.  */
+	return (to_do == 0 || to_do == n) ? EOF : n - to_do;
 
       /* Try to maintain alignment: write a whole number of blocks.
 	 dont_write is what gets left over. */