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 | |
parent | b1848fdeec705bc7d2f64e3a365f1ff66eeb4f0d (diff) | |
download | glibc-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')
-rw-r--r-- | libio/fileops.c | 18 | ||||
-rw-r--r-- | libio/iopadn.c | 2 | ||||
-rw-r--r-- | libio/iowpadn.c | 4 | ||||
-rw-r--r-- | libio/libioP.h | 5 |
4 files changed, 15 insertions, 14 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. */ diff --git a/libio/iopadn.c b/libio/iopadn.c index 7e374508f0..b7a4c5a739 100644 --- a/libio/iopadn.c +++ b/libio/iopadn.c @@ -59,7 +59,7 @@ _IO_padn (fp, pad, count) w = _IO_sputn (fp, padptr, PADSIZE); written += w; if (w != PADSIZE) - return written; + return w == EOF ? w : written; } if (i > 0) diff --git a/libio/iowpadn.c b/libio/iowpadn.c index 05632d5bf0..56e4b8ccb2 100644 --- a/libio/iowpadn.c +++ b/libio/iowpadn.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993, 1997, 1999 Free Software Foundation, Inc. +/* Copyright (C) 1993-2012 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -65,7 +65,7 @@ _IO_wpadn (fp, pad, count) w = _IO_sputn (fp, (char *) padptr, PADSIZE); written += w; if (w != PADSIZE) - return written; + return w == EOF ? w : written; } if (i > 0) diff --git a/libio/libioP.h b/libio/libioP.h index fe81115094..a402958b9c 100644 --- a/libio/libioP.h +++ b/libio/libioP.h @@ -1,5 +1,4 @@ -/* Copyright (C) 1993, 1997-2003,2004,2005,2006,2007,2012 - Free Software Foundation, Inc. +/* Copyright (C) 1993-2012 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -167,7 +166,7 @@ typedef int (*_IO_pbackfail_t) (_IO_FILE *, int); #define _IO_WPBACKFAIL(FP, CH) WJUMP1 (__pbackfail, FP, CH) /* The 'xsputn' hook writes upto N characters from buffer DATA. - Returns the number of character actually written. + Returns EOF or the number of character actually written. It matches the streambuf::xsputn virtual function. */ typedef _IO_size_t (*_IO_xsputn_t) (_IO_FILE *FP, const void *DATA, _IO_size_t N); |