aboutsummaryrefslogtreecommitdiff
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.zip
glibc-04b76b5aa8b2d1d19066e42dd1a56a38f34e274c.tar.gz
glibc-04b76b5aa8b2d1d19066e42dd1a56a38f34e274c.tar.bz2
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 c5ec5f7..6a088b1 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;