[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