diff options
author | Siddhesh Poyarekar <siddhesh@redhat.com> | 2012-11-16 19:13:11 +0530 |
---|---|---|
committer | Siddhesh Poyarekar <siddhesh@redhat.com> | 2012-11-16 19:13:11 +0530 |
commit | 2b766585f9b4ffabeef2f36200c275976b93f2c7 (patch) | |
tree | d6be89abc6bfa88e5e9fd997bb4cfd94b035adc2 /libio/fileops.c | |
parent | b1848fdeec705bc7d2f64e3a365f1ff66eeb4f0d (diff) | |
download | glibc-2b766585f9b4ffabeef2f36200c275976b93f2c7.tar.gz |
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.c | 18 |
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. */ |