about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--NEWS9
-rw-r--r--sysdeps/mach/hurd/i386/libc.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/aarch64/libc.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/alpha/libc.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/arc/libc.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/arm/be/libc.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/arm/le/libc.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/csky/libc.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/hppa/libc.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/i386/libc.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/ia64/libc.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/microblaze/be/libc.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/microblaze/le/libc.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/nios2/libc.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/or1k/libc.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/sh/be/libc.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/sh/le/libc.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/64/libc.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist2
-rw-r--r--wcsmbs/Makefile2
-rw-r--r--wcsmbs/Versions3
-rw-r--r--wcsmbs/c8rtomb.c132
-rw-r--r--wcsmbs/mbrtoc8.c126
-rw-r--r--wcsmbs/uchar.h21
40 files changed, 360 insertions, 1 deletions
diff --git a/NEWS b/NEWS
index dbf351b895..df882ec243 100644
--- a/NEWS
+++ b/NEWS
@@ -51,6 +51,15 @@ Major new features:
   Previously, input bytes not within the ASCII range resulted in
   unpredictable output.
 
+* Support for the mbrtoc8 and c8rtomb multibyte/UTF-8 character conversion
+  functions has been added per the ISO C2X N2653 and C++20 P0482R6 proposals.
+  Support for the char8_t typedef has been added per the ISO C2X N2653
+  proposal.  The functions are declared in uchar.h in C2X mode or when the
+  _GNU_SOURCE macro or C++20 __cpp_char8_t feature test macro is defined.
+  The char8_t typedef is declared in uchar.h in C2X mode or when the
+  _GNU_SOURCE macro is defined and the C++20 __cpp_char8_t feature test macro
+  is not defined (if __cpp_char8_t is defined, then char8_t is a builtin type).
+
 Deprecated and removed features, and other changes affecting compatibility:
 
 * Support for prelink will be removed in the next release; this includes
diff --git a/sysdeps/mach/hurd/i386/libc.abilist b/sysdeps/mach/hurd/i386/libc.abilist
index 4dc87e9061..66fb0e28fa 100644
--- a/sysdeps/mach/hurd/i386/libc.abilist
+++ b/sysdeps/mach/hurd/i386/libc.abilist
@@ -2289,6 +2289,8 @@ GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
 GLIBC_2.35 close_range F
 GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
+GLIBC_2.36 mbrtoc8 F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
index 16d34b55c6..516b029d30 100644
--- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
@@ -2616,10 +2616,12 @@ GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
 GLIBC_2.35 epoll_pwait2 F
 GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
 GLIBC_2.36 fsconfig F
 GLIBC_2.36 fsmount F
 GLIBC_2.36 fsopen F
 GLIBC_2.36 fspick F
+GLIBC_2.36 mbrtoc8 F
 GLIBC_2.36 mount_setattr F
 GLIBC_2.36 move_mount F
 GLIBC_2.36 open_tree F
diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist
index 3f794bea0f..dde08899fe 100644
--- a/sysdeps/unix/sysv/linux/alpha/libc.abilist
+++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist
@@ -2713,10 +2713,12 @@ GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
 GLIBC_2.35 epoll_pwait2 F
 GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
 GLIBC_2.36 fsconfig F
 GLIBC_2.36 fsmount F
 GLIBC_2.36 fsopen F
 GLIBC_2.36 fspick F
+GLIBC_2.36 mbrtoc8 F
 GLIBC_2.36 mount_setattr F
 GLIBC_2.36 move_mount F
 GLIBC_2.36 open_tree F
diff --git a/sysdeps/unix/sysv/linux/arc/libc.abilist b/sysdeps/unix/sysv/linux/arc/libc.abilist
index 072627810c..ade44d3029 100644
--- a/sysdeps/unix/sysv/linux/arc/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arc/libc.abilist
@@ -2377,10 +2377,12 @@ GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
 GLIBC_2.35 epoll_pwait2 F
 GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
 GLIBC_2.36 fsconfig F
 GLIBC_2.36 fsmount F
 GLIBC_2.36 fsopen F
 GLIBC_2.36 fspick F
+GLIBC_2.36 mbrtoc8 F
 GLIBC_2.36 mount_setattr F
 GLIBC_2.36 move_mount F
 GLIBC_2.36 open_tree F
diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
index dbd5f07e6e..98b33708af 100644
--- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
@@ -496,10 +496,12 @@ GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
 GLIBC_2.35 epoll_pwait2 F
 GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
 GLIBC_2.36 fsconfig F
 GLIBC_2.36 fsmount F
 GLIBC_2.36 fsopen F
 GLIBC_2.36 fspick F
+GLIBC_2.36 mbrtoc8 F
 GLIBC_2.36 mount_setattr F
 GLIBC_2.36 move_mount F
 GLIBC_2.36 open_tree F
diff --git a/sysdeps/unix/sysv/linux/arm/le/libc.abilist b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
index 0f02d79faa..05dbbe5bcc 100644
--- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
@@ -493,10 +493,12 @@ GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
 GLIBC_2.35 epoll_pwait2 F
 GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
 GLIBC_2.36 fsconfig F
 GLIBC_2.36 fsmount F
 GLIBC_2.36 fsopen F
 GLIBC_2.36 fspick F
+GLIBC_2.36 mbrtoc8 F
 GLIBC_2.36 mount_setattr F
 GLIBC_2.36 move_mount F
 GLIBC_2.36 open_tree F
diff --git a/sysdeps/unix/sysv/linux/csky/libc.abilist b/sysdeps/unix/sysv/linux/csky/libc.abilist
index 11d3b36a78..430a24349e 100644
--- a/sysdeps/unix/sysv/linux/csky/libc.abilist
+++ b/sysdeps/unix/sysv/linux/csky/libc.abilist
@@ -2652,10 +2652,12 @@ GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
 GLIBC_2.35 epoll_pwait2 F
 GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
 GLIBC_2.36 fsconfig F
 GLIBC_2.36 fsmount F
 GLIBC_2.36 fsopen F
 GLIBC_2.36 fspick F
+GLIBC_2.36 mbrtoc8 F
 GLIBC_2.36 mount_setattr F
 GLIBC_2.36 move_mount F
 GLIBC_2.36 open_tree F
diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist
index 5caa1321b1..de44616526 100644
--- a/sysdeps/unix/sysv/linux/hppa/libc.abilist
+++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist
@@ -2601,10 +2601,12 @@ GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
 GLIBC_2.35 epoll_pwait2 F
 GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
 GLIBC_2.36 fsconfig F
 GLIBC_2.36 fsmount F
 GLIBC_2.36 fsopen F
 GLIBC_2.36 fspick F
+GLIBC_2.36 mbrtoc8 F
 GLIBC_2.36 mount_setattr F
 GLIBC_2.36 move_mount F
 GLIBC_2.36 open_tree F
diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist
index 276d7d5619..18b4fbf26e 100644
--- a/sysdeps/unix/sysv/linux/i386/libc.abilist
+++ b/sysdeps/unix/sysv/linux/i386/libc.abilist
@@ -2785,10 +2785,12 @@ GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
 GLIBC_2.35 epoll_pwait2 F
 GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
 GLIBC_2.36 fsconfig F
 GLIBC_2.36 fsmount F
 GLIBC_2.36 fsopen F
 GLIBC_2.36 fspick F
+GLIBC_2.36 mbrtoc8 F
 GLIBC_2.36 mount_setattr F
 GLIBC_2.36 move_mount F
 GLIBC_2.36 open_tree F
diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist
index 5e2249518e..a8e959d417 100644
--- a/sysdeps/unix/sysv/linux/ia64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist
@@ -2551,10 +2551,12 @@ GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
 GLIBC_2.35 epoll_pwait2 F
 GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
 GLIBC_2.36 fsconfig F
 GLIBC_2.36 fsmount F
 GLIBC_2.36 fsopen F
 GLIBC_2.36 fspick F
+GLIBC_2.36 mbrtoc8 F
 GLIBC_2.36 mount_setattr F
 GLIBC_2.36 move_mount F
 GLIBC_2.36 open_tree F
diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
index 802469a5b9..3a7e4ef6e4 100644
--- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
@@ -497,10 +497,12 @@ GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
 GLIBC_2.35 epoll_pwait2 F
 GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
 GLIBC_2.36 fsconfig F
 GLIBC_2.36 fsmount F
 GLIBC_2.36 fsopen F
 GLIBC_2.36 fspick F
+GLIBC_2.36 mbrtoc8 F
 GLIBC_2.36 mount_setattr F
 GLIBC_2.36 move_mount F
 GLIBC_2.36 open_tree F
diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
index 2f949397df..864ad2cdf8 100644
--- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
@@ -2728,10 +2728,12 @@ GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
 GLIBC_2.35 epoll_pwait2 F
 GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
 GLIBC_2.36 fsconfig F
 GLIBC_2.36 fsmount F
 GLIBC_2.36 fsopen F
 GLIBC_2.36 fspick F
+GLIBC_2.36 mbrtoc8 F
 GLIBC_2.36 mount_setattr F
 GLIBC_2.36 move_mount F
 GLIBC_2.36 open_tree F
diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
index f63cc9cd4c..163058420d 100644
--- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
@@ -2701,10 +2701,12 @@ GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
 GLIBC_2.35 epoll_pwait2 F
 GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
 GLIBC_2.36 fsconfig F
 GLIBC_2.36 fsmount F
 GLIBC_2.36 fsopen F
 GLIBC_2.36 fspick F
+GLIBC_2.36 mbrtoc8 F
 GLIBC_2.36 mount_setattr F
 GLIBC_2.36 move_mount F
 GLIBC_2.36 open_tree F
diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
index 88d2b707f9..a6debfda56 100644
--- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
@@ -2698,10 +2698,12 @@ GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
 GLIBC_2.35 epoll_pwait2 F
 GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
 GLIBC_2.36 fsconfig F
 GLIBC_2.36 fsmount F
 GLIBC_2.36 fsopen F
 GLIBC_2.36 fspick F
+GLIBC_2.36 mbrtoc8 F
 GLIBC_2.36 mount_setattr F
 GLIBC_2.36 move_mount F
 GLIBC_2.36 open_tree F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
index 6c2bc0ee78..2b53d888de 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
@@ -2693,10 +2693,12 @@ GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
 GLIBC_2.35 epoll_pwait2 F
 GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
 GLIBC_2.36 fsconfig F
 GLIBC_2.36 fsmount F
 GLIBC_2.36 fsopen F
 GLIBC_2.36 fspick F
+GLIBC_2.36 mbrtoc8 F
 GLIBC_2.36 mount_setattr F
 GLIBC_2.36 move_mount F
 GLIBC_2.36 open_tree F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
index 09c9980d95..849aae4130 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
@@ -2691,10 +2691,12 @@ GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
 GLIBC_2.35 epoll_pwait2 F
 GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
 GLIBC_2.36 fsconfig F
 GLIBC_2.36 fsmount F
 GLIBC_2.36 fsopen F
 GLIBC_2.36 fspick F
+GLIBC_2.36 mbrtoc8 F
 GLIBC_2.36 mount_setattr F
 GLIBC_2.36 move_mount F
 GLIBC_2.36 open_tree F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
index 763920ea8f..37f6c1bf58 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
@@ -2699,10 +2699,12 @@ GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
 GLIBC_2.35 epoll_pwait2 F
 GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
 GLIBC_2.36 fsconfig F
 GLIBC_2.36 fsmount F
 GLIBC_2.36 fsopen F
 GLIBC_2.36 fspick F
+GLIBC_2.36 mbrtoc8 F
 GLIBC_2.36 mount_setattr F
 GLIBC_2.36 move_mount F
 GLIBC_2.36 open_tree F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
index 36d30558c1..ff1eb91e10 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
@@ -2602,10 +2602,12 @@ GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
 GLIBC_2.35 epoll_pwait2 F
 GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
 GLIBC_2.36 fsconfig F
 GLIBC_2.36 fsmount F
 GLIBC_2.36 fsopen F
 GLIBC_2.36 fspick F
+GLIBC_2.36 mbrtoc8 F
 GLIBC_2.36 mount_setattr F
 GLIBC_2.36 move_mount F
 GLIBC_2.36 open_tree F
diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist
index e4383fe464..361b91f547 100644
--- a/sysdeps/unix/sysv/linux/nios2/libc.abilist
+++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist
@@ -2740,10 +2740,12 @@ GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
 GLIBC_2.35 epoll_pwait2 F
 GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
 GLIBC_2.36 fsconfig F
 GLIBC_2.36 fsmount F
 GLIBC_2.36 fsopen F
 GLIBC_2.36 fspick F
+GLIBC_2.36 mbrtoc8 F
 GLIBC_2.36 mount_setattr F
 GLIBC_2.36 move_mount F
 GLIBC_2.36 open_tree F
diff --git a/sysdeps/unix/sysv/linux/or1k/libc.abilist b/sysdeps/unix/sysv/linux/or1k/libc.abilist
index 735a8eea7e..cb91606377 100644
--- a/sysdeps/unix/sysv/linux/or1k/libc.abilist
+++ b/sysdeps/unix/sysv/linux/or1k/libc.abilist
@@ -2123,10 +2123,12 @@ GLIBC_2.35 wprintf F
 GLIBC_2.35 write F
 GLIBC_2.35 writev F
 GLIBC_2.35 wscanf F
+GLIBC_2.36 c8rtomb F
 GLIBC_2.36 fsconfig F
 GLIBC_2.36 fsmount F
 GLIBC_2.36 fsopen F
 GLIBC_2.36 fspick F
+GLIBC_2.36 mbrtoc8 F
 GLIBC_2.36 mount_setattr F
 GLIBC_2.36 move_mount F
 GLIBC_2.36 open_tree F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
index 715dd31afe..1264aff6ef 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
@@ -2755,10 +2755,12 @@ GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
 GLIBC_2.35 epoll_pwait2 F
 GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
 GLIBC_2.36 fsconfig F
 GLIBC_2.36 fsmount F
 GLIBC_2.36 fsopen F
 GLIBC_2.36 fspick F
+GLIBC_2.36 mbrtoc8 F
 GLIBC_2.36 mount_setattr F
 GLIBC_2.36 move_mount F
 GLIBC_2.36 open_tree F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
index ac4b69e5fc..f96d6e37b5 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
@@ -2788,10 +2788,12 @@ GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
 GLIBC_2.35 epoll_pwait2 F
 GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
 GLIBC_2.36 fsconfig F
 GLIBC_2.36 fsmount F
 GLIBC_2.36 fsopen F
 GLIBC_2.36 fspick F
+GLIBC_2.36 mbrtoc8 F
 GLIBC_2.36 mount_setattr F
 GLIBC_2.36 move_mount F
 GLIBC_2.36 open_tree F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
index fd42f1bc11..e7082e1bd3 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
@@ -2510,10 +2510,12 @@ GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
 GLIBC_2.35 epoll_pwait2 F
 GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
 GLIBC_2.36 fsconfig F
 GLIBC_2.36 fsmount F
 GLIBC_2.36 fsopen F
 GLIBC_2.36 fspick F
+GLIBC_2.36 mbrtoc8 F
 GLIBC_2.36 mount_setattr F
 GLIBC_2.36 move_mount F
 GLIBC_2.36 open_tree F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
index 24688916dd..1032c7e46a 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
@@ -2812,10 +2812,12 @@ GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
 GLIBC_2.35 epoll_pwait2 F
 GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
 GLIBC_2.36 fsconfig F
 GLIBC_2.36 fsmount F
 GLIBC_2.36 fsopen F
 GLIBC_2.36 fspick F
+GLIBC_2.36 mbrtoc8 F
 GLIBC_2.36 mount_setattr F
 GLIBC_2.36 move_mount F
 GLIBC_2.36 open_tree F
diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
index 536eddf9f1..f932db7c22 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
@@ -2379,10 +2379,12 @@ GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
 GLIBC_2.35 epoll_pwait2 F
 GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
 GLIBC_2.36 fsconfig F
 GLIBC_2.36 fsmount F
 GLIBC_2.36 fsopen F
 GLIBC_2.36 fspick F
+GLIBC_2.36 mbrtoc8 F
 GLIBC_2.36 mount_setattr F
 GLIBC_2.36 move_mount F
 GLIBC_2.36 open_tree F
diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
index 214b4f1c87..ccc53b0bb8 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
@@ -2579,10 +2579,12 @@ GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
 GLIBC_2.35 epoll_pwait2 F
 GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
 GLIBC_2.36 fsconfig F
 GLIBC_2.36 fsmount F
 GLIBC_2.36 fsopen F
 GLIBC_2.36 fspick F
+GLIBC_2.36 mbrtoc8 F
 GLIBC_2.36 mount_setattr F
 GLIBC_2.36 move_mount F
 GLIBC_2.36 open_tree F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
index bd738a4eb8..dbf6501007 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
@@ -2753,10 +2753,12 @@ GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
 GLIBC_2.35 epoll_pwait2 F
 GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
 GLIBC_2.36 fsconfig F
 GLIBC_2.36 fsmount F
 GLIBC_2.36 fsopen F
 GLIBC_2.36 fspick F
+GLIBC_2.36 mbrtoc8 F
 GLIBC_2.36 mount_setattr F
 GLIBC_2.36 move_mount F
 GLIBC_2.36 open_tree F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
index 170361236a..98f08a01b6 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
@@ -2547,10 +2547,12 @@ GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
 GLIBC_2.35 epoll_pwait2 F
 GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
 GLIBC_2.36 fsconfig F
 GLIBC_2.36 fsmount F
 GLIBC_2.36 fsopen F
 GLIBC_2.36 fspick F
+GLIBC_2.36 mbrtoc8 F
 GLIBC_2.36 mount_setattr F
 GLIBC_2.36 move_mount F
 GLIBC_2.36 open_tree F
diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
index 88fcd03300..df11cc8f13 100644
--- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
@@ -2608,10 +2608,12 @@ GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
 GLIBC_2.35 epoll_pwait2 F
 GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
 GLIBC_2.36 fsconfig F
 GLIBC_2.36 fsmount F
 GLIBC_2.36 fsopen F
 GLIBC_2.36 fspick F
+GLIBC_2.36 mbrtoc8 F
 GLIBC_2.36 mount_setattr F
 GLIBC_2.36 move_mount F
 GLIBC_2.36 open_tree F
diff --git a/sysdeps/unix/sysv/linux/sh/le/libc.abilist b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
index f1115ef46d..4ee5513d18 100644
--- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
@@ -2605,10 +2605,12 @@ GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
 GLIBC_2.35 epoll_pwait2 F
 GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
 GLIBC_2.36 fsconfig F
 GLIBC_2.36 fsmount F
 GLIBC_2.36 fsopen F
 GLIBC_2.36 fspick F
+GLIBC_2.36 mbrtoc8 F
 GLIBC_2.36 mount_setattr F
 GLIBC_2.36 move_mount F
 GLIBC_2.36 open_tree F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
index 6063da1acf..3cefa76871 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
@@ -2748,10 +2748,12 @@ GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
 GLIBC_2.35 epoll_pwait2 F
 GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
 GLIBC_2.36 fsconfig F
 GLIBC_2.36 fsmount F
 GLIBC_2.36 fsopen F
 GLIBC_2.36 fspick F
+GLIBC_2.36 mbrtoc8 F
 GLIBC_2.36 mount_setattr F
 GLIBC_2.36 move_mount F
 GLIBC_2.36 open_tree F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
index 780d2c0987..e3ea5c4383 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
@@ -2574,10 +2574,12 @@ GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
 GLIBC_2.35 epoll_pwait2 F
 GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
 GLIBC_2.36 fsconfig F
 GLIBC_2.36 fsmount F
 GLIBC_2.36 fsopen F
 GLIBC_2.36 fspick F
+GLIBC_2.36 mbrtoc8 F
 GLIBC_2.36 mount_setattr F
 GLIBC_2.36 move_mount F
 GLIBC_2.36 open_tree F
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
index 56cad609fe..2944bc7837 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
@@ -2525,10 +2525,12 @@ GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
 GLIBC_2.35 epoll_pwait2 F
 GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
 GLIBC_2.36 fsconfig F
 GLIBC_2.36 fsmount F
 GLIBC_2.36 fsopen F
 GLIBC_2.36 fspick F
+GLIBC_2.36 mbrtoc8 F
 GLIBC_2.36 mount_setattr F
 GLIBC_2.36 move_mount F
 GLIBC_2.36 open_tree F
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
index 2ed242a62d..47296193af 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
@@ -2631,10 +2631,12 @@ GLIBC_2.35 __memcmpeq F
 GLIBC_2.35 _dl_find_object F
 GLIBC_2.35 epoll_pwait2 F
 GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 c8rtomb F
 GLIBC_2.36 fsconfig F
 GLIBC_2.36 fsmount F
 GLIBC_2.36 fsopen F
 GLIBC_2.36 fspick F
+GLIBC_2.36 mbrtoc8 F
 GLIBC_2.36 mount_setattr F
 GLIBC_2.36 move_mount F
 GLIBC_2.36 open_tree F
diff --git a/wcsmbs/Makefile b/wcsmbs/Makefile
index df9a85f4a9..bda281ad70 100644
--- a/wcsmbs/Makefile
+++ b/wcsmbs/Makefile
@@ -42,7 +42,7 @@ routines := wcscat wcschr wcscmp wcscpy wcscspn wcsdup wcslen wcsncat \
 	    wcsmbsload mbsrtowcs_l \
 	    isoc99_wscanf isoc99_vwscanf isoc99_fwscanf isoc99_vfwscanf \
 	    isoc99_swscanf isoc99_vswscanf \
-	    mbrtoc16 c16rtomb mbrtoc32 c32rtomb
+	    mbrtoc8 c8rtomb mbrtoc16 c16rtomb mbrtoc32 c32rtomb
 
 strop-tests :=  wcscmp wcsncmp wmemcmp wcslen wcschr wcsrchr wcscpy wcsnlen \
 		wcpcpy wcsncpy wcpncpy wcscat wcsncat wcschrnul wcsspn wcspbrk \
diff --git a/wcsmbs/Versions b/wcsmbs/Versions
index 0b31c1b940..ec28acfb73 100644
--- a/wcsmbs/Versions
+++ b/wcsmbs/Versions
@@ -49,4 +49,7 @@ libc {
     wcstof32; wcstof64; wcstof32x;
     wcstof32_l; wcstof64_l; wcstof32x_l;
   }
+  GLIBC_2.36 {
+    c8rtomb; mbrtoc8;
+  }
 }
diff --git a/wcsmbs/c8rtomb.c b/wcsmbs/c8rtomb.c
new file mode 100644
index 0000000000..b564770eb5
--- /dev/null
+++ b/wcsmbs/c8rtomb.c
@@ -0,0 +1,132 @@
+/* UTF-8 to multibyte conversion.
+   Copyright (C) 2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <errno.h>
+#include <uchar.h>
+#include <wchar.h>
+
+
+/* This is the private state used if PS is NULL.  */
+static mbstate_t state;
+
+size_t
+c8rtomb (char *s, char8_t c8, mbstate_t *ps)
+{
+  /* This implementation depends on the converter invoked by wcrtomb not
+     needing to retain state in either the top most bit of ps->__count or
+     in ps->__value between invocations.  This implementation uses the
+     top most bit of ps->__count to indicate that trailing code units are
+     expected and uses ps->__value to store previously seen code units.  */
+
+  wchar_t wc;
+
+  if (ps == NULL)
+    ps = &state;
+
+  if (s == NULL)
+    {
+      /* if 's' is a null pointer, behave as if u8'\0' was passed as 'c8'.  If
+         this occurs for an incomplete code unit sequence, then an error will
+         be reported below.  */
+      c8 = u8""[0];
+    }
+
+  if (! (ps->__count & 0x80000000))
+    {
+      /* Initial state.  */
+      if ((c8 >= 0x80 && c8 <= 0xC1) || c8 >= 0xF5)
+	{
+	  /* An invalid lead code unit.  */
+	  __set_errno (EILSEQ);
+	  return -1;
+	}
+      if (c8 >= 0xC2)
+	{
+	  /* A valid lead code unit.  */
+	  ps->__count |= 0x80000000;
+	  ps->__value.__wchb[0] = c8;
+	  ps->__value.__wchb[3] = 1;
+	  return 0;
+	}
+      /* A single byte (ASCII) code unit.  */
+      wc = c8;
+    }
+  else
+    {
+      char8_t cu1 = ps->__value.__wchb[0];
+      if (ps->__value.__wchb[3] == 1)
+	{
+	  /* A single lead code unit was previously seen.  */
+	  if ((c8 < 0x80 || c8 > 0xBF)
+              || (cu1 == 0xE0 && c8 < 0xA0)
+              || (cu1 == 0xED && c8 > 0x9F)
+              || (cu1 == 0xF0 && c8 < 0x90)
+              || (cu1 == 0xF4 && c8 > 0x8F))
+	    {
+	      /* An invalid second code unit.  */
+	      __set_errno (EILSEQ);
+	      return -1;
+	    }
+	  if (cu1 >= 0xE0)
+	    {
+	      /* A three or four code unit sequence.  */
+	      ps->__value.__wchb[1] = c8;
+	      ++ps->__value.__wchb[3];
+	      return 0;
+	    }
+	  wc = ((cu1 & 0x1F) << 6)
+	       + (c8 & 0x3F);
+	}
+      else
+	{
+	  char8_t cu2 = ps->__value.__wchb[1];
+	  /* A three or four byte code unit sequence.  */
+	  if (c8 < 0x80 || c8 > 0xBF)
+	    {
+	      /* An invalid third or fourth code unit.  */
+	      __set_errno (EILSEQ);
+	      return -1;
+	    }
+	  if (ps->__value.__wchb[3] == 2 && cu1 >= 0xF0)
+	    {
+	      /* A four code unit sequence.  */
+	      ps->__value.__wchb[2] = c8;
+	      ++ps->__value.__wchb[3];
+	      return 0;
+	    }
+	  if (cu1 < 0xF0)
+	    {
+	      wc = ((cu1 & 0x0F) << 12)
+		   + ((cu2 & 0x3F) << 6)
+		   + (c8 & 0x3F);
+	    }
+	  else
+	    {
+	      char8_t cu3 = ps->__value.__wchb[2];
+	      wc = ((cu1 & 0x07) << 18)
+		   + ((cu2 & 0x3F) << 12)
+		   + ((cu3 & 0x3F) << 6)
+		   + (c8 & 0x3F);
+	    }
+	}
+      ps->__count &= 0x7fffffff;
+      ps->__value.__wch = 0;
+    }
+
+  return wcrtomb (s, wc, ps);
+}
diff --git a/wcsmbs/mbrtoc8.c b/wcsmbs/mbrtoc8.c
new file mode 100644
index 0000000000..dd80b5282d
--- /dev/null
+++ b/wcsmbs/mbrtoc8.c
@@ -0,0 +1,126 @@
+/* Multibyte to UTF-8 conversion.
+   Copyright (C) 2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <assert.h>
+#include <dlfcn.h>
+#include <errno.h>
+#include <gconv.h>
+#include <uchar.h>
+#include <wcsmbsload.h>
+
+#include <sysdep.h>
+
+#ifndef EILSEQ
+# define EILSEQ EINVAL
+#endif
+
+
+/* This is the private state used if PS is NULL.  */
+static mbstate_t state;
+
+size_t
+mbrtoc8 (char8_t *pc8, const char *s, size_t n, mbstate_t *ps)
+{
+  /* This implementation depends on the converter invoked by mbrtowc not
+     needing to retain state in either the top most bit of ps->__count or
+     in ps->__value between invocations.  This implementation uses the
+     top most bit of ps->__count to indicate that trailing code units are
+     yet to be written and uses ps->__value to store those code units.  */
+
+  if (ps == NULL)
+    ps = &state;
+
+  /* If state indicates that trailing code units are yet to be written, write
+     those first regardless of whether 's' is a null pointer.  */
+  if (ps->__count & 0x80000000)
+    {
+      /* ps->__value.__wchb[3] stores the index of the next code unit to
+         write.  Code units are stored in reverse order.  */
+      size_t i = ps->__value.__wchb[3];
+      if (pc8 != NULL)
+	{
+	  *pc8 = ps->__value.__wchb[i];
+	}
+      if (i == 0)
+	{
+	  ps->__count &= 0x7fffffff;
+	  ps->__value.__wch = 0;
+	}
+      else
+	--ps->__value.__wchb[3];
+      return -3;
+    }
+
+  if (s == NULL)
+    {
+      /* if 's' is a null pointer, behave as if a null pointer was passed for
+         'pc8', an empty string was passed for 's', and 1 passed for 'n'.  */
+      pc8 = NULL;
+      s = "";
+      n = 1;
+    }
+
+  wchar_t wc;
+  size_t result;
+
+  result = mbrtowc (&wc, s, n, ps);
+  if (result <= n)
+    {
+      if (wc <= 0x7F)
+	{
+	  if (pc8 != NULL)
+	    *pc8 = wc;
+	}
+      else if (wc <= 0x7FF)
+	{
+	  if (pc8 != NULL)
+	    *pc8 = 0xC0 + ((wc >> 6) & 0x1F);
+	  ps->__value.__wchb[0] = 0x80 + (wc & 0x3F);
+	  ps->__value.__wchb[3] = 0;
+	  ps->__count |= 0x80000000;
+	}
+      else if (wc <= 0xFFFF)
+	{
+	  if (pc8 != NULL)
+	    *pc8 = 0xE0 + ((wc >> 12) & 0x0F);
+	  ps->__value.__wchb[1] = 0x80 + ((wc >> 6) & 0x3F);
+	  ps->__value.__wchb[0] = 0x80 + (wc & 0x3F);
+	  ps->__value.__wchb[3] = 1;
+	  ps->__count |= 0x80000000;
+	}
+      else if (wc <= 0x10FFFF)
+	{
+	  if (pc8 != NULL)
+	    *pc8 = 0xF0 + ((wc >> 18) & 0x07);
+	  ps->__value.__wchb[2] = 0x80 + ((wc >> 12) & 0x3F);
+	  ps->__value.__wchb[1] = 0x80 + ((wc >> 6) & 0x3F);
+	  ps->__value.__wchb[0] = 0x80 + (wc & 0x3F);
+	  ps->__value.__wchb[3] = 2;
+	  ps->__count |= 0x80000000;
+	}
+    }
+  if (result == 0 && wc != 0)
+    {
+      /* mbrtowc() never returns -3.  When a MB sequence converts to multiple
+         WCs, no input is consumed when writing the subsequent WCs resulting
+         in a result of 0 even if a null character wasn't written.  */
+      result = -3;
+    }
+
+  return result;
+}
diff --git a/wcsmbs/uchar.h b/wcsmbs/uchar.h
index 051cdcbeb5..c37e8619a0 100644
--- a/wcsmbs/uchar.h
+++ b/wcsmbs/uchar.h
@@ -31,6 +31,13 @@
 #include <bits/types.h>
 #include <bits/types/mbstate_t.h>
 
+/* Declare the C2x char8_t typedef in C2x modes, but only if the C++
+  __cpp_char8_t feature test macro is not defined.  */
+#if __GLIBC_USE (ISOC2X) && !defined __cpp_char8_t
+/* Define the 8-bit character type.  */
+typedef unsigned char char8_t;
+#endif
+
 #ifndef __USE_ISOCXX11
 /* Define the 16-bit and 32-bit character types.  */
 typedef __uint_least16_t char16_t;
@@ -40,6 +47,20 @@ typedef __uint_least32_t char32_t;
 
 __BEGIN_DECLS
 
+/* Declare the C2x mbrtoc8() and c8rtomb() functions in C2x modes or if
+   the C++ __cpp_char8_t feature test macro is defined.  */
+#if __GLIBC_USE (ISOC2X) || defined __cpp_char8_t
+/* Write char8_t representation of multibyte character pointed
+   to by S to PC8.  */
+extern size_t mbrtoc8  (char8_t *__restrict __pc8,
+			const char *__restrict __s, size_t __n,
+			mbstate_t *__restrict __p) __THROW;
+
+/* Write multibyte representation of char8_t C8 to S.  */
+extern size_t c8rtomb  (char *__restrict __s, char8_t __c8,
+			mbstate_t *__restrict __ps) __THROW;
+#endif
+
 /* Write char16_t representation of multibyte character pointed
    to by S to PC16.  */
 extern size_t mbrtoc16 (char16_t *__restrict __pc16,