diff options
author | Rémi Denis-Courmont <remi@remlab.net> | 2010-04-21 18:37:48 +0200 |
---|---|---|
committer | Jaroslav Kysela <perex@perex.cz> | 2010-04-21 19:20:39 +0200 |
commit | 8d80d5f344ae5e32d24122cbf8e759fdd1e1a60d (patch) | |
tree | fa1bda4a3eddd41e704acff8c846c1e3e11dd024 | |
parent | 51ef640cee37f73d771e784e81196ff7c15f53ff (diff) | |
download | alsa-lib-8d80d5f344ae5e32d24122cbf8e759fdd1e1a60d.tar.gz |
Use thread-safe locale functions if available
setlocale() is not thread-safe. It can actually trigger a crash if
another thread uses locale informations at the same time in the process.
Library code should use POSIX newlocale/duplocale/uselocale/freelocale
instead. Those functions only change the locale data for the calling
thread.
Signed-off-by: Rémi Denis-Courmont <remi@remlab.net>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
-rw-r--r-- | src/conf.c | 16 |
1 files changed, 16 insertions, 0 deletions
@@ -499,22 +499,38 @@ static int safe_strtod(const char *str, double *val) { char *end; double v; +#ifdef HAVE_USELOCALE + locale_t saved_locale, c_locale; +#else char *saved_locale; char locstr[64]; /* enough? */ +#endif int err; if (!*str) return -EINVAL; +#ifdef HAVE_USELOCALE + c_locale = newlocale(LC_NUMERIC_MASK, "C", 0); + saved_locale = uselocale(c_locale); +#else saved_locale = setlocale(LC_NUMERIC, NULL); if (saved_locale) { snprintf(locstr, sizeof(locstr), "%s", saved_locale); setlocale(LC_NUMERIC, "C"); } +#endif errno = 0; v = strtod(str, &end); err = -errno; +#ifdef HAVE_USELOCALE + if (c_locale != (locale_t)0) { + uselocale(saved_locale); + freelocale(c_locale); + } +#else if (saved_locale) setlocale(LC_NUMERIC, locstr); +#endif if (err) return err; if (*end) |