about summary refs log tree commit diff
path: root/libio/wfileops.c
diff options
context:
space:
mode:
authorAndreas Schwab <schwab@suse.de>2014-10-30 12:18:48 +0100
committerAndreas Schwab <schwab@suse.de>2014-11-03 09:58:24 +0100
commit04b76b5aa8b2d1d19066e42dd1a56a38f34e274c (patch)
tree4dfc80ec8c905d6dbe0bb2ea4d54a9b02178b9ca /libio/wfileops.c
parent4c6da7da9fb1f0f94e668e6d2966a4f50a7f0d85 (diff)
downloadglibc-04b76b5aa8b2d1d19066e42dd1a56a38f34e274c.tar.gz
glibc-04b76b5aa8b2d1d19066e42dd1a56a38f34e274c.tar.xz
glibc-04b76b5aa8b2d1d19066e42dd1a56a38f34e274c.zip
Don't error out writing a multibyte character to an unbuffered stream (bug 17522)
Diffstat (limited to 'libio/wfileops.c')
-rw-r--r--libio/wfileops.c25
1 files changed, 20 insertions, 5 deletions
diff --git a/libio/wfileops.c b/libio/wfileops.c
index c5ec5f7a27..6a088b1c15 100644
--- a/libio/wfileops.c
+++ b/libio/wfileops.c
@@ -75,17 +75,32 @@ _IO_wdo_write (fp, data, to_do)
 	{
 	  enum __codecvt_result result;
 	  const wchar_t *new_data;
+	  char mb_buf[MB_LEN_MAX];
+	  char *write_base, *write_ptr, *buf_end;
+
+	  if (fp->_IO_write_ptr - fp->_IO_write_base < sizeof (mb_buf))
+	    {
+	      /* Make sure we have room for at least one multibyte
+		 character.  */
+	      write_ptr = write_base = mb_buf;
+	      buf_end = mb_buf + sizeof (mb_buf);
+	    }
+	  else
+	    {
+	      write_ptr = fp->_IO_write_ptr;
+	      write_base = fp->_IO_write_base;
+	      buf_end = fp->_IO_buf_end;
+	    }
 
 	  /* Now convert from the internal format into the external buffer.  */
 	  result = (*cc->__codecvt_do_out) (cc, &fp->_wide_data->_IO_state,
 					    data, data + to_do, &new_data,
-					    fp->_IO_write_ptr,
-					    fp->_IO_buf_end,
-					    &fp->_IO_write_ptr);
+					    write_ptr,
+					    buf_end,
+					    &write_ptr);
 
 	  /* Write out what we produced so far.  */
-	  if (_IO_new_do_write (fp, fp->_IO_write_base,
-				fp->_IO_write_ptr - fp->_IO_write_base) == EOF)
+	  if (_IO_new_do_write (fp, write_base, write_ptr - write_base) == EOF)
 	    /* Something went wrong.  */
 	    return WEOF;