In perl.git, the branch blead has been updated <https://perl5.git.perl.org/perl.git/commitdiff/c6fbd3534700ea217d0e7553adb13aaaf116c6a6?hp=63e5b0d74e16f32c89cdb039e79f0fdb47d1b819>
- Log ----------------------------------------------------------------- commit c6fbd3534700ea217d0e7553adb13aaaf116c6a6 Author: Karl Williamson <k...@cpan.org> Date: Thu Nov 9 18:46:17 2017 -0700 sv.c: Fix typo in comment commit c656fadc5045091645f773ff71cfe0039be5ddaf Author: Karl Williamson <k...@cpan.org> Date: Thu Nov 9 18:38:02 2017 -0700 malloc.c: Fix typo in comment commit 149651df9be1c2d09b767da7cad61d661cd5222b Author: Karl Williamson <k...@cpan.org> Date: Thu Nov 9 18:37:30 2017 -0700 lib/locale.t: Clarify test name commit 464decb62c023e46cc194963698a26d39b491f4d Author: Karl Williamson <k...@cpan.org> Date: Thu Nov 9 18:26:43 2017 -0700 handy.h: Clarify comment commit 43cb665150ddf892c277cba7edc80937fa053fb1 Author: Karl Williamson <k...@cpan.org> Date: Mon Sep 11 18:57:54 2017 -0600 locale.c: strerror_l() not fool proof Commit 7aaa36b196e5a478a3d1bd32506797db7cebf0b2 changed to use strerror_l() if available on the platform. But there is a potential bug with this on threaded perls. The code uses strerror_l() when it needs the answer on a locale that isn't necessarily the current one. But it uses plain strerror() when the locale is known to be the current one. Plain strerror() isn't necessarily thread-safe. However, on systems that have strerror_r(), reentr.h has caused our apparent call to plain strerror() to instead call the thread-safe strerror_r() under the hood. So there is no bug on unthreaded perls nor on ones that have strerror_r(). This commit fixes the bug on threaded builds which have strerror_l() but not strerror_r(). It does this by using strerror_l() for everything, and constructing a locale object that is the current locale to use when the locale doesn't need to be changed. This is somewhat more work than the alternative above does, so that one is used if available. No changes are made to how it works on systems that don't have strerror_l(). Some systems have deprecated strerror_r(). reentr.h does not use it on such systems. The reason for the deprecation, we would hope, may be that the plain strerror() is implemented thread-safely. We don't know that, so we just assume that the plain version is thread-unsafe. We do have tests that try to find races here, but they haven't shown any. It could be that systems that are advanced enough to have strerror_l() also have strerror_r(). ----------------------------------------------------------------------- Summary of changes: handy.h | 5 +++-- lib/locale.t | 2 +- locale.c | 41 +++++++++++++++++++++++++++++++++++++++-- malloc.c | 2 +- sv.c | 2 +- 5 files changed, 45 insertions(+), 7 deletions(-) diff --git a/handy.h b/handy.h index 53477994a3..f75c900656 100644 --- a/handy.h +++ b/handy.h @@ -260,8 +260,9 @@ typedef U64TYPE U64; #endif -/* log(2) is pretty close to 0.30103, just in case anyone is grepping for it */ -#define BIT_DIGITS(N) (((N)*146)/485 + 1) /* log2(10) =~ 146/485 */ +/* log(2) (i.e., log base 10 of 2) is pretty close to 0.30103, just in case + * anyone is grepping for it */ +#define BIT_DIGITS(N) (((N)*146)/485 + 1) /* log10(2) =~ 146/485 */ #define TYPE_DIGITS(T) BIT_DIGITS(sizeof(T) * 8) #define TYPE_CHARS(T) (TYPE_DIGITS(T) + 2) /* sign, NUL */ diff --git a/lib/locale.t b/lib/locale.t index cb39d06208..85843acae7 100644 --- a/lib/locale.t +++ b/lib/locale.t @@ -2258,7 +2258,7 @@ foreach my $Locale (@Locale) { # OS X 10.9.3 report_result($Locale, ++$locales_test_number, $ok21); - $test_names{$locales_test_number} = '"$!" is ASCII only outside of locale scope'; + $test_names{$locales_test_number} = '"$!" is ASCII-only outside of locale scope'; debug "$first_f_test..$locales_test_number: \$f = $f, \$g = $g, back to locale = $Locale\n"; diff --git a/locale.c b/locale.c index d56fd40016..436456a8c2 100644 --- a/locale.c +++ b/locale.c @@ -3403,7 +3403,17 @@ Perl_my_strerror(pTHX_ const int errnum) # if defined(HAS_POSIX_2008_LOCALE) && defined(HAS_STRERROR_L) - /* This function is trivial if we have strerror_l() */ + /* This function is trivial if we don't have to worry about thread safety + * and have strerror_l(), as it handles the switch of locales so we don't + * have to deal with that. We don't have to worry about thread safety if + * this is an unthreaded build, or if strerror_r() is also available. Both + * it and strerror_l() are thread-safe. Plain strerror() isn't thread + * safe. But on threaded builds when strerror_r() is available, the + * apparent call to strerror() below is actually a macro that + * behind-the-scenes calls strerror_r(). + */ + +# if ! defined(USE_ITHREADS) || defined(HAS_STRERROR_R) if (within_locale_scope) { errstr = savepv(strerror(errnum)); @@ -3412,7 +3422,34 @@ Perl_my_strerror(pTHX_ const int errnum) errstr = savepv(strerror_l(errnum, PL_C_locale_obj)); } -# else /* Doesn't have strerror_l(). */ +# else + + /* Here we have strerror_l(), but not strerror_r() and we are on a + * threaded-build. We use strerror_l() for everything, constructing a + * locale to pass to it if necessary */ + + bool do_free = FALSE; + locale_t locale_to_use; + + if (within_locale_scope) { + locale_to_use = uselocale((locale_t) 0); + if (locale_to_use == LC_GLOBAL_LOCALE) { + locale_to_use = duplocale(LC_GLOBAL_LOCALE); + do_free = TRUE; + } + } + else { /* Use C locale if not within 'use locale' scope */ + locale_to_use = PL_C_locale_obj; + } + + errstr = savepv(strerror_l(errnum, locale_to_use)); + + if (do_free) { + freelocale(locale_to_use); + } + +# endif +# else /* Doesn't have strerror_l() */ # ifdef USE_POSIX_2008_LOCALE diff --git a/malloc.c b/malloc.c index 1809ab3b8d..bb72cddef1 100644 --- a/malloc.c +++ b/malloc.c @@ -1655,7 +1655,7 @@ morecore(int bucket) return; #ifndef NO_PERL_MALLOC_ENV if (!were_called) { - /* It's the our first time. Initialize ourselves */ + /* It's our first time. Initialize ourselves */ were_called = 1; /* Avoid a loop */ if (!MallocCfg[MallocCfg_skip_cfg_env]) { char *s = getenv("PERL_MALLOC_OPT"), *t = s, *off; diff --git a/sv.c b/sv.c index 225e5c855a..c1a33fb0a0 100644 --- a/sv.c +++ b/sv.c @@ -11921,7 +11921,7 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p bool has_utf8 = DO_UTF8(sv); /* has the result utf8? */ const bool pat_utf8 = has_utf8; /* the pattern is in utf8? */ /* Times 4: a decimal digit takes more than 3 binary digits. - * NV_DIG: mantissa takes than many decimal digits. + * NV_DIG: mantissa takes that many decimal digits. * Plus 32: Playing safe. */ char ebuf[IV_DIG * 4 + NV_DIG + 32]; bool no_redundant_warning = FALSE; /* did we use any explicit format parameter index? */ -- Perl5 Master Repository