From 2b766585f9b4ffabeef2f36200c275976b93f2c7 Mon Sep 17 00:00:00 2001 From: Siddhesh Poyarekar Date: Fri, 16 Nov 2012 19:13:11 +0530 Subject: printf should return negative value on error [BZ #11741] Fixed bug where printf and family may return a spurious success when printing padded formats. --- libio/fileops.c | 18 ++++++++++-------- libio/iopadn.c | 2 +- libio/iowpadn.c | 4 ++-- libio/libioP.h | 5 ++--- 4 files changed, 15 insertions(+), 14 deletions(-) (limited to 'libio') 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); -- cgit v1.2.3