summaryrefslogtreecommitdiff
path: root/locale.c
diff options
context:
space:
mode:
authorKarl Williamson <khw@cpan.org>2020-01-03 22:18:02 -0700
committerKarl Williamson <khw@cpan.org>2020-02-19 22:09:48 -0700
commit5a6637f01ac3edd837722b6d156ddb2250ea049f (patch)
treef6138a6fbd869dcd0a560fffcd31a0aca1321556 /locale.c
parent63bebc1439c3a3eefd310e674f2593ff60cceca4 (diff)
downloadperl-5a6637f01ac3edd837722b6d156ddb2250ea049f.tar.gz
Fixup POSIX::mbtowc, wctomb
This commit enhances these functions so that on threaded perls, they use mbrtowc and wcrtomb when available, making them thread safe. The substitution isn't completely transparent, as no effort is made to hide any differences in errno setting upon error. And there may be slight differences in edge case behavior on some platforms. This commit also changes the behaviors so that they take a scalar parameter instead of a char *, and this might be 'undef' or not be forceable into a valid PV. If not a PV, the functions initialize the shift state. Previously the shift state was always reinitialized with every call, which meant these could not work on locales with shift states. In addition, there were several issues in mbtowc and wctomb that this commit fixes. mbtowc and wctomb, when used, are now run with a semaphore. This avoids races if called at the same time in another thread. The returned wide character from mbtowc() could well have been garbage. The final parameter to mbtowc is now optional, as passing an SV allows us to determine the length without the need for an extra parameter. It is now used only to restrict the parsing of the string to shorter than the actual length. wctomb would segfault if the string parameter was shared or hadn't been pre-allocated with a string of sufficient length to hold the result.
Diffstat (limited to 'locale.c')
-rw-r--r--locale.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/locale.c b/locale.c
index 787474b9a7..d68ef50e1b 100644
--- a/locale.c
+++ b/locale.c
@@ -3461,11 +3461,17 @@ Perl_init_i18nl10n(pTHX_ int printwarn)
# endif
# endif /* DEBUGGING */
- /* Initialize the per-thread mbrFOO() state variable. See POSIX.xs for
- * why this particular incantation is used. */
+ /* Initialize the per-thread mbrFOO() state variables. See POSIX.xs for
+ * why these particular incantations are used. */
#ifdef HAS_MBRLEN
memzero(&PL_mbrlen_ps, sizeof(PL_mbrlen_ps));
#endif
+#ifdef HAS_MBRTOWC
+ memzero(&PL_mbrtowc_ps, sizeof(PL_mbrtowc_ps));
+#endif
+#ifdef HAS_WCTOMBR
+ wcrtomb(NULL, L'\0', &PL_wcrtomb_ps);
+#endif
/* Initialize the cache of the program's UTF-8ness for the always known
* locales C and POSIX */