summary refs log tree commit diff
path: root/stdio-common
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 /stdio-common
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 'stdio-common')
-rw-r--r--stdio-common/tst-put-error.c26
-rw-r--r--stdio-common/vfprintf.c28
2 files changed, 50 insertions, 4 deletions
diff --git a/stdio-common/tst-put-error.c b/stdio-common/tst-put-error.c
index 115dbd509a..7b95491725 100644
--- a/stdio-common/tst-put-error.c
+++ b/stdio-common/tst-put-error.c
@@ -1,3 +1,22 @@
+/* Verify that print functions return error when there is an I/O error.
+
+   Copyright (C) 2005-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
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
 #include <errno.h>
 #include <error.h>
 #include <stdio.h>
@@ -26,6 +45,13 @@ do_test (void)
   printf ("fprintf = %d\n", n);
   if (n >= 0)
     error (EXIT_FAILURE, 0, "second fprintf succeeded");
+
+  /* Padded printing takes a different code path.  */
+  n = fprintf (fp, "%10000s", "foo");
+  printf ("fprintf = %d\n", n);
+  if (n >= 0)
+    error (EXIT_FAILURE, 0, "padded fprintf succeeded");
+
   return 0;
 }
 
diff --git a/stdio-common/vfprintf.c b/stdio-common/vfprintf.c
index 17d3f42a97..0c1339febd 100644
--- a/stdio-common/vfprintf.c
+++ b/stdio-common/vfprintf.c
@@ -87,8 +87,18 @@
 
 # define PUT(F, S, N)	_IO_sputn ((F), (S), (N))
 # define PAD(Padchar) \
-  if (width > 0)							      \
-    done_add (_IO_padn (s, (Padchar), width))
+  do {									      \
+    if (width > 0)							      \
+      {									      \
+	unsigned int d = _IO_padn (s, (Padchar), width);		      \
+	if (__builtin_expect (d == EOF, 0))				      \
+	  {								      \
+	    done = -1;							      \
+	    goto all_done;						      \
+	  }								      \
+	done_add (d);							      \
+      }									      \
+  } while (0)
 # define PUTC(C, F)	_IO_putc_unlocked (C, F)
 # define ORIENT		if (_IO_vtable_offset (s) == 0 && _IO_fwide (s, -1) != -1)\
 			  return -1
@@ -106,8 +116,18 @@
 
 # define PUT(F, S, N)	_IO_sputn ((F), (S), (N))
 # define PAD(Padchar) \
-  if (width > 0)							      \
-    done_add (_IO_wpadn (s, (Padchar), width))
+  do {									      \
+    if (width > 0)							      \
+      {									      \
+	unsigned int d = _IO_wpadn (s, (Padchar), width);		      \
+	if (__builtin_expect (d == EOF, 0))				      \
+	  {								      \
+	    done = -1;							      \
+	    goto all_done;						      \
+	  }								      \
+	done_add (d);							      \
+      }									      \
+  } while (0)
 # define PUTC(C, F)	_IO_putwc_unlocked (C, F)
 # define ORIENT		if (_IO_fwide (s, 1) != 1) return -1