commit 0f88acf52504636f56b73132285c7355b1beb0af
parent 84128eaf37e33fed023f271018b157b7398ad91c
Author: Roberto E. Vargas Caballero <k0ga@shike2.net>
Date: Mon, 5 Jan 2026 20:24:01 +0100
libc: Include a mbstate_t in FILE
Several of the file operations related to wchar require
a mbstate_t, and every stream should have its own mbstate_t
and not using the hidden state of several of the conversion
functions.
Diffstat:
13 files changed, 37 insertions(+), 45 deletions(-)
diff --git a/include/scc/bits/amd64/arch/cdefs.h b/include/scc/bits/amd64/arch/cdefs.h
@@ -1,9 +1,6 @@
-#ifdef _NEED_VA_LIST
-#ifndef _VA_LIST
+#ifndef _CDEF_H
typedef __builtin_va_list __va_list;
-#define _VA_LIST
-#endif
-#undef _NEED_VA_LIST
+typedef int __wchar_t;
#endif
#ifdef _NEED_SIZET
@@ -31,7 +28,7 @@ typedef long ptrdiff_t;
#ifdef _NEED_WCHART
#ifndef _WCHART
-typedef int wchar_t;
+typedef __wchar_t wchar_t;
#define _WCHART
#endif
#undef _NEED_WCHART
diff --git a/include/scc/bits/arm/arch/cdefs.h b/include/scc/bits/arm/arch/cdefs.h
@@ -1,9 +1,6 @@
-#ifdef _NEED_VA_LIST
-#ifndef _VA_LIST
+#ifndef _CDEF_H
typedef __builtin_va_list __va_list;
-#define _VA_LIST
-#endif
-#undef _NEED_VA_LIST
+typedef int __wchar_t;
#endif
#ifdef _NEED_SIZET
@@ -31,7 +28,7 @@ typedef long ptrdiff_t;
#ifdef _NEED_WCHART
#ifndef _WCHART
-typedef int wchar_t;
+typedef __wchar_t wchar_t;
#define _WCHART
#endif
#undef _NEED_WCHART
diff --git a/include/scc/bits/arm64/arch/cdefs.h b/include/scc/bits/arm64/arch/cdefs.h
@@ -1,9 +1,6 @@
-#ifdef _NEED_VA_LIST
-#ifndef _VA_LIST
+#ifndef _CDEF_H
typedef __builtin_va_list __va_list;
-#define _VA_LIST
-#endif
-#undef _NEED_VA_LIST
+typedef int __wchar_t;
#endif
#ifdef _NEED_SIZET
@@ -31,7 +28,7 @@ typedef long ptrdiff_t;
#ifdef _NEED_WCHART
#ifndef _WCHART
-typedef int wchar_t;
+typedef __wchar_t wchar_t;
#define _WCHART
#endif
#undef _NEED_WCHART
diff --git a/include/scc/bits/i386/arch/cdefs.h b/include/scc/bits/i386/arch/cdefs.h
@@ -1,9 +1,6 @@
-#ifdef _NEED_VA_LIST
-#ifndef _VA_LIST
+#ifndef _CDEF_H
typedef __builtin_va_list __va_list;
-#define _VA_LIST
-#endif
-#undef _NEED_VA_LIST
+typedef int __wchar_t;
#endif
#ifdef _NEED_SIZET
@@ -31,7 +28,7 @@ typedef long ptrdiff_t;
#ifdef _NEED_WCHART
#ifndef _WCHART
-typedef int wchar_t;
+typedef __wchar_t wchar_t;
#define _WCHART
#endif
#undef _NEED_WCHART
diff --git a/include/scc/bits/ppc/arch/cdefs.h b/include/scc/bits/ppc/arch/cdefs.h
@@ -1,9 +1,6 @@
-#ifdef _NEED_VA_LIST
-#ifndef _VA_LIST
+#ifndef _CDEF_H
typedef __builtin_va_list __va_list;
-#define _VA_LIST
-#endif
-#undef _NEED_VA_LIST
+typedef int __wchar_t;
#endif
#ifdef _NEED_SIZET
@@ -31,7 +28,7 @@ typedef long ptrdiff_t;
#ifdef _NEED_WCHART
#ifndef _WCHART
-typedef int wchar_t;
+typedef __wchar_t wchar_t;
#define _WCHART
#endif
#undef _NEED_WCHART
diff --git a/include/scc/bits/wchar.h b/include/scc/bits/wchar.h
@@ -0,0 +1,8 @@
+#ifndef BITS_WCHAR_H
+#define BITS_WCHAR_H
+typedef struct {
+ unsigned char oc;
+ unsigned char sh;
+ __wchar_t wc;
+} __mbstate_t;
+#endif
diff --git a/include/scc/bits/z80/arch/cdefs.h b/include/scc/bits/z80/arch/cdefs.h
@@ -1,9 +1,6 @@
-#ifdef _NEED_VA_LIST
-#ifndef _VA_LIST
+#ifndef _CDEF_H
typedef __builtin_va_list __va_list;
-#define _VA_LIST
-#endif
-#undef _NEED_VA_LIST
+typedef int __wchar_t;
#endif
#ifdef _NEED_SIZET
@@ -31,7 +28,7 @@ typedef short ptrdiff_t;
#ifdef _NEED_WCHART
#ifndef _WCHART
-typedef int wchar_t;
+typedef __wchar_t wchar_t;
#define _WCHART
#endif
#undef _NEED_WCHART
diff --git a/include/scc/stdarg.h b/include/scc/stdarg.h
@@ -1,7 +1,6 @@
#ifndef _STDARG_H
#define _STDARG_H
-#define _NEED_VA_LIST
#include <arch/cdefs.h>
typedef __va_list va_list;
diff --git a/include/scc/stdio.h b/include/scc/stdio.h
@@ -3,9 +3,9 @@
#define _NEED_NULL
#define _NEED_SIZET
-#define _NEED_VA_LIST
#include <sys/stdio.h>
#include <arch/cdefs.h>
+#include <bits/wchar.h>
#ifndef FOPEN_MAX
#define FOPEN_MAX 12
@@ -64,6 +64,7 @@ typedef struct _FILE {
size_t len;
unsigned short flags;
unsigned char unbuf[1];
+ __mbstate_t mbs;
} FILE;
extern FILE __iob[FOPEN_MAX];
diff --git a/include/scc/wchar.h b/include/scc/wchar.h
@@ -7,15 +7,11 @@
#define _NEED_WEOF
#define _NEED_WCHARLIM
#define _NEED_WINT
-#define _NEED_VA_LIST
#include <arch/cdefs.h>
#include <sys/cdefs.h>
+#include <bits/wchar.h>
-typedef struct {
- unsigned char oc;
- unsigned char sh;
- wchar_t wc;
-} mbstate_t;
+typedef __mbstate_t mbstate_t;
struct tm;
struct _FILE;
diff --git a/src/libc/stdio/_fpopen.c b/src/libc/stdio/_fpopen.c
@@ -1,6 +1,8 @@
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
+#include <wchar.h>
#include <sys.h>
@@ -62,6 +64,7 @@ _fpopen(const char *restrict fname,
if ((fd = _open(fname, flags, rights)) < 0)
return NULL;
+ memset(&fp->mbs, 0, sizeof(mbstate_t));
fp->buf = NULL;
fp->fd = fd;
diff --git a/src/libc/stdio/clearerr.c b/src/libc/stdio/clearerr.c
@@ -1,4 +1,6 @@
#include <stdio.h>
+#include <string.h>
+#include <wchar.h>
#undef clearerr
@@ -6,4 +8,5 @@ void
clearerr(FILE *fp)
{
fp->flags &= ~(_IOERR | _IOEOF);
+ memset(&fp->mbs, 0, sizeof(mbstate_t));
}
diff --git a/src/libc/wchar/fputwc.c b/src/libc/wchar/fputwc.c
@@ -11,7 +11,7 @@ _fputwc(wchar_t wc, FILE *fp, int *np)
int n;
char buf[MB_LEN_MAX];
- if ((n = wcrtomb(buf, wc, NULL)) == -1)
+ if ((n = wcrtomb(buf, wc, &fp->mbs)) == -1)
goto err;
if (fwrite(buf, 1, n, fp) < n)
goto err;