[vlc-devel] [PATCH] Use strerror if strerror_l is unavailable.
Rémi Denis-Courmont
remi at remlab.net
Sun Jul 17 18:44:23 CEST 2016
Le perjantaina 15. heinäkuuta 2016, 14.19.06 EEST Richard Diamond a écrit :
> A few libc's (namely Newlib) don't provide strerror_l. On these platforms,
> this patch instead uses the locale indifferent strerror_r. Since a missing
> strerror_l probably implies that the libc in question doesn't implement any
> part of the locale API (ie only supports the 'C' or 'POSIX' locales), this
> patch just uses the default locale (ie 'C'/American English).
>
> ---
> configure.ac | 1 +
> src/posix/error.c | 54
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55
> insertions(+)
>
> diff --git a/configure.ac b/configure.ac
> index 492ce40..37d1286 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -590,6 +590,7 @@ AC_REPLACE_FUNCS([gettimeofday])
> AC_CHECK_FUNCS(fdatasync,,
> [AC_DEFINE(fdatasync, fsync, [Alias fdatasync() to fsync() if missing.])
> ])
> +AC_CHECK_FUNCS(strerror_l,,[AC_FUNC_STRERROR_R])
Checking for strerror_r is useless here (since you don´t provide a fallback
for that).
>
> dnl mingw64 implements those as static inline, not functions with C linkage
> VLC_REPLACE_DECL([asprintf], [#include <stdio.h>])
> diff --git a/src/posix/error.c b/src/posix/error.c
> index db51004..9bd2929 100644
> --- a/src/posix/error.c
> +++ b/src/posix/error.c
> @@ -29,8 +29,31 @@
>
> #include <vlc_common.h>
>
> +#ifndef HAVE_STRERROR_L
> +# ifndef HAVE_STRERROR_R
> +# error Need strerror_l or strerror_r.
> +# endif
> +
> +# include <vlc_threads.h>
> +# include <vlc_atomic.h>
> +
> +static atomic_bool error_string_inited = ATOMIC_VAR_INIT(false);
> +static vlc_mutex_t error_string_initing_mtx = VLC_STATIC_MUTEX;
> +static vlc_threadvar_t error_string;
> +static void error_string_free(void* str) {
> + if(str != NULL) {
> + free(str);
> + }
> +}
> +
> +#define ERROR_STRING_SIZE 256
> +
> +#endif
> +
> +
> static const char *vlc_strerror_l(int errnum, const char *lname)
> {
> +#ifdef HAVE_STRERROR_L
> int saved_errno = errno;
> locale_t loc = newlocale(LC_MESSAGES_MASK, lname, (locale_t)0);
>
> @@ -51,6 +74,37 @@ static const char *vlc_strerror_l(int errnum, const char
> *lname) const char *buf = strerror_l(errnum, loc);
>
> freelocale(loc);
> +#else
> + if(!atomic_load_explicit(&error_string_inited, memory_order_relaxed)) {
> + vlc_mutex_lock(&error_string_initing_mtx);
> + if(!atomic_load_explicit(&error_string_inited, memory_order_relaxed))
pthread_once would be much simpler.
Also the thread local variable handle is leaked. I don't mind, but maybe
somebody else has another opinion.
> { +
> + if(vlc_threadvar_create(&error_string, &error_string_free) ==
> VLC_SUCCESS) { + atomic_store_explicit(&error_string_inited, true,
> memory_order_seq_cst); + } else {
> + vlc_mutex_unlock(&error_string_initing_mtx);
> + return NULL;
> + }
> + }
> + vlc_mutex_unlock(&error_string_initing_mtx);
> + }
> +
> + char* buf = vlc_threadvar_get(error_string);
> + if(buf == NULL) {
> + buf = calloc(ERROR_STRING_SIZE, sizeof(char));
> + if(buf == NULL) {
> + return NULL;
> + } else {
> + if(vlc_threadvar_set(error_string, (void*)buf) != VLC_SUCCESS) {
> + free(buf);
> + return NULL;
> + }
> + }
> + }
> +
> + strerror_r(errnum, buf, ERROR_STRING_SIZE);
> +
> +#endif
> return buf;
> }
--
Rémi Denis-Courmont
http://www.remlab.net/
More information about the vlc-devel
mailing list