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
This commit is contained in:
Tim J. Robbins 2003-11-12 08:49:12 +00:00
parent a82652a49f
commit 909a17f41a
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=122547

View file

@ -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,
@ -155,6 +156,34 @@ __sbprintf(FILE *fp, const wchar_t *fmt, va_list ap)
return (ret);
}
/*
* 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
*/
@ -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) { \