summaryrefslogtreecommitdiffstats
path: root/lib/libc
diff options
context:
space:
mode:
authortjr <tjr@FreeBSD.org>2003-11-12 08:49:12 +0000
committertjr <tjr@FreeBSD.org>2003-11-12 08:49:12 +0000
commit7a8b48f087c4a62a12071799a28207667b63a16b (patch)
tree4f1c64b78bbc04a578ca7c5b40d14387302ad2d5 /lib/libc
parentaabfe725f2f55fa838b7dab6ab99e790b0f27ef7 (diff)
downloadFreeBSD-src-7a8b48f087c4a62a12071799a28207667b63a16b.zip
FreeBSD-src-7a8b48f087c4a62a12071799a28207667b63a16b.tar.gz
Use __sfvwrite() instead of __sputc() via __fputwc() to write to fake
string files (__SSTR flag set). This is necessary because __sputc() does not respect the __SALC flag, and crashes trying to flush the buffer instead of resizing it. PR: 59167
Diffstat (limited to 'lib/libc')
-rw-r--r--lib/libc/stdio/vfwprintf.c31
1 files changed, 30 insertions, 1 deletions
diff --git a/lib/libc/stdio/vfwprintf.c b/lib/libc/stdio/vfwprintf.c
index 3be9365..a679288 100644
--- a/lib/libc/stdio/vfwprintf.c
+++ b/lib/libc/stdio/vfwprintf.c
@@ -114,6 +114,7 @@ enum typeid {
};
static int __sbprintf(FILE *, const wchar_t *, va_list);
+static wint_t __xfputwc(wchar_t, FILE *);
static wchar_t *__ujtoa(uintmax_t, wchar_t *, int, int, const wchar_t *, int,
char, const char *);
static wchar_t *__ultoa(u_long, wchar_t *, int, int, const wchar_t *, int,
@@ -156,6 +157,34 @@ __sbprintf(FILE *fp, const wchar_t *fmt, va_list ap)
}
/*
+ * Like __fputwc, but handles fake string (__SSTR) files properly.
+ * File must already be locked.
+ */
+static wint_t
+__xfputwc(wchar_t wc, FILE *fp)
+{
+ char buf[MB_LEN_MAX];
+ struct __suio uio;
+ struct __siov iov;
+ size_t i, len;
+ int ret;
+
+ if ((fp->_flags & __SSTR) == 0)
+ return (__fputwc(wc, fp));
+
+ if ((len = wcrtomb(buf, wc, NULL)) == (size_t)-1) {
+ fp->_flags |= __SERR;
+ return (WEOF);
+ }
+ uio.uio_iov = &iov;
+ uio.uio_resid = len;
+ uio.uio_iovcnt = 1;
+ iov.iov_base = buf;
+ iov.iov_len = len;
+ return (__sfvwrite(fp, &uio) != EOF ? (wint_t)wc : WEOF);
+}
+
+/*
* Macros for converting digits to letters and vice versa
*/
#define to_digit(c) ((c) - '0')
@@ -529,7 +558,7 @@ __vfwprintf(FILE *fp, const wchar_t *fmt0, va_list ap)
*/
#define PRINT(ptr, len) do { \
for (n3 = 0; n3 < (len); n3++) \
- __fputwc((ptr)[n3], fp); \
+ __xfputwc((ptr)[n3], fp); \
} while (0)
#define PAD(howmany, with) do { \
if ((n = (howmany)) > 0) { \
OpenPOWER on IntegriCloud