summaryrefslogtreecommitdiff
path: root/libio
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
parentb1848fdeec705bc7d2f64e3a365f1ff66eeb4f0d (diff)
downloadglibc-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')
-rw-r--r--libio/fileops.c18
-rw-r--r--libio/iopadn.c2
-rw-r--r--libio/iowpadn.c4
-rw-r--r--libio/libioP.h5
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);