bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: use of thread-unsafe localeconv in vasprintf


From: Bruno Haible
Subject: Re: use of thread-unsafe localeconv in vasprintf
Date: Fri, 23 Mar 2007 01:35:59 +0100
User-agent: KMail/1.5.4

Simon Josefsson wrote:
> Any objections to installing this patch?

Yes. I think it's a shame to return a non-POSIX-compliant result if there
are better possibilities. The appended patch is in my queue for a few days;
I'm meaning to test it a little more before I commit it.

> I searched a little, but could not find any thread-safe replacement
> for localeconv standardized anywhere, so I guess disabling it is the
> only option.

There are at least two other options:
  - Use nl_langinfo. nl_langinfo is not documented to be thread-safe, but
    since it only returns constant strings that don't depend on any
    parameter except the locale, it's likely that most implementors will
    have the strings precomputed in some libc-private storage.
  - Establish a table of the decimal-point character for all locales in the
    system at configuration time. Store them in a C file that presents a
    MT-safe API for accessing it.

Bruno


*** lib/vasnprintf.c    22 Mar 2007 02:04:01 -0000      1.32
--- lib/vasnprintf.c    23 Mar 2007 00:15:03 -0000
***************
*** 41,46 ****
--- 41,49 ----
  #include <errno.h>    /* errno */
  #include <limits.h>   /* CHAR_BIT */
  #include <float.h>    /* DBL_MAX_EXP, LDBL_MAX_EXP */
+ #if HAVE_NL_LANGINFO
+ # include <langinfo.h>
+ #endif
  #if WIDE_CHAR_VERSION
  # include "wprintf-parse.h"
  #else
***************
*** 504,511 ****
                              if ((flags & FLAG_ALT)
                                  || mantissa > 0.0L || precision > 0)
                                {
!                                 const char *point =
!                                   localeconv () -> decimal_point;
                                  /* The decimal point is always a single byte:
                                     either '.' or ','.  */
                                  *p++ = (point[0] != '\0' ? point[0] : '.');
--- 507,521 ----
                              if ((flags & FLAG_ALT)
                                  || mantissa > 0.0L || precision > 0)
                                {
!                                 const char *point;
!                                 /* Prefer nl_langinfo() over localeconv(),
!                                    since the latter is not multithread-
!                                    safe.  */
! #  if HAVE_NL_LANGINFO
!                                 point = nl_langinfo (RADIXCHAR);
! #  else
!                                 point = localeconv () -> decimal_point;
! #  endif
                                  /* The decimal point is always a single byte:
                                     either '.' or ','.  */
                                  *p++ = (point[0] != '\0' ? point[0] : '.');
***************
*** 654,661 ****
                              if ((flags & FLAG_ALT)
                                  || mantissa > 0.0 || precision > 0)
                                {
!                                 const char *point =
!                                   localeconv () -> decimal_point;
                                  /* The decimal point is always a single byte:
                                     either '.' or ','.  */
                                  *p++ = (point[0] != '\0' ? point[0] : '.');
--- 664,678 ----
                              if ((flags & FLAG_ALT)
                                  || mantissa > 0.0 || precision > 0)
                                {
!                                 const char *point;
!                                 /* Prefer nl_langinfo() over localeconv(),
!                                    since the latter is not multithread-
!                                    safe.  */
! #  if HAVE_NL_LANGINFO
!                                 point = nl_langinfo (RADIXCHAR);
! #  else
!                                 point = localeconv () -> decimal_point;
! #  endif
                                  /* The decimal point is always a single byte:
                                     either '.' or ','.  */
                                  *p++ = (point[0] != '\0' ? point[0] : '.');
*** m4/fprintf-posix.m4 9 Mar 2007 02:59:39 -0000       1.1
--- m4/fprintf-posix.m4 23 Mar 2007 00:15:03 -0000
***************
*** 1,4 ****
! # fprintf-posix.m4 serial 1
  dnl Copyright (C) 2007 Free Software Foundation, Inc.
  dnl This file is free software; the Free Software Foundation
  dnl gives unlimited permission to copy and/or distribute it,
--- 1,4 ----
! # fprintf-posix.m4 serial 2
  dnl Copyright (C) 2007 Free Software Foundation, Inc.
  dnl This file is free software; the Free Software Foundation
  dnl gives unlimited permission to copy and/or distribute it,
***************
*** 31,41 ****
        ;;
    esac
    if test $gl_cv_func_fprintf_posix = no; then
!     if ! expr "$gl_cv_func_printf_directive_a" : ".*yes" > /dev/null; then
!       AC_DEFINE([NEED_PRINTF_DIRECTIVE_A], 1,
!         [Define if the vasnprintf implementation needs special code for
!          the 'a' and 'A' directives.])
!     fi
      gl_REPLACE_VASNPRINTF
      gl_REPLACE_FPRINTF
    fi
--- 31,37 ----
        ;;
    esac
    if test $gl_cv_func_fprintf_posix = no; then
!     gl_PREREQ_VASNPRINTF_DIRECTIVE_A
      gl_REPLACE_VASNPRINTF
      gl_REPLACE_FPRINTF
    fi
*** m4/snprintf-posix.m4        9 Mar 2007 01:24:32 -0000       1.2
--- m4/snprintf-posix.m4        23 Mar 2007 00:15:03 -0000
***************
*** 1,4 ****
! # snprintf-posix.m4 serial 1
  dnl Copyright (C) 2007 Free Software Foundation, Inc.
  dnl This file is free software; the Free Software Foundation
  dnl gives unlimited permission to copy and/or distribute it,
--- 1,4 ----
! # snprintf-posix.m4 serial 2
  dnl Copyright (C) 2007 Free Software Foundation, Inc.
  dnl This file is free software; the Free Software Foundation
  dnl gives unlimited permission to copy and/or distribute it,
***************
*** 50,60 ****
      esac
    fi
    if test $gl_cv_func_snprintf_posix = no; then
!     if ! expr "$gl_cv_func_printf_directive_a" : ".*yes" > /dev/null; then
!       AC_DEFINE([NEED_PRINTF_DIRECTIVE_A], 1,
!         [Define if the vasnprintf implementation needs special code for
!          the 'a' and 'A' directives.])
!     fi
      gl_REPLACE_VASNPRINTF
      gl_REPLACE_SNPRINTF
    fi
--- 50,56 ----
      esac
    fi
    if test $gl_cv_func_snprintf_posix = no; then
!     gl_PREREQ_VASNPRINTF_DIRECTIVE_A
      gl_REPLACE_VASNPRINTF
      gl_REPLACE_SNPRINTF
    fi
*** m4/sprintf-posix.m4 9 Mar 2007 01:24:32 -0000       1.2
--- m4/sprintf-posix.m4 23 Mar 2007 00:15:03 -0000
***************
*** 1,4 ****
! # sprintf-posix.m4 serial 1
  dnl Copyright (C) 2007 Free Software Foundation, Inc.
  dnl This file is free software; the Free Software Foundation
  dnl gives unlimited permission to copy and/or distribute it,
--- 1,4 ----
! # sprintf-posix.m4 serial 2
  dnl Copyright (C) 2007 Free Software Foundation, Inc.
  dnl This file is free software; the Free Software Foundation
  dnl gives unlimited permission to copy and/or distribute it,
***************
*** 31,41 ****
        ;;
    esac
    if test $gl_cv_func_sprintf_posix = no; then
!     if ! expr "$gl_cv_func_printf_directive_a" : ".*yes" > /dev/null; then
!       AC_DEFINE([NEED_PRINTF_DIRECTIVE_A], 1,
!         [Define if the vasnprintf implementation needs special code for
!          the 'a' and 'A' directives.])
!     fi
      gl_REPLACE_VASNPRINTF
      gl_REPLACE_SPRINTF
    fi
--- 31,37 ----
        ;;
    esac
    if test $gl_cv_func_sprintf_posix = no; then
!     gl_PREREQ_VASNPRINTF_DIRECTIVE_A
      gl_REPLACE_VASNPRINTF
      gl_REPLACE_SPRINTF
    fi
*** m4/vasnprintf-posix.m4      9 Mar 2007 01:24:32 -0000       1.5
--- m4/vasnprintf-posix.m4      23 Mar 2007 00:15:03 -0000
***************
*** 1,4 ****
! # vasnprintf-posix.m4 serial 2
  dnl Copyright (C) 2007 Free Software Foundation, Inc.
  dnl This file is free software; the Free Software Foundation
  dnl gives unlimited permission to copy and/or distribute it,
--- 1,4 ----
! # vasnprintf-posix.m4 serial 3
  dnl Copyright (C) 2007 Free Software Foundation, Inc.
  dnl This file is free software; the Free Software Foundation
  dnl gives unlimited permission to copy and/or distribute it,
***************
*** 34,44 ****
        ;;
    esac
    if test $gl_cv_func_vasnprintf_posix = no; then
!     if ! expr "$gl_cv_func_printf_directive_a" : ".*yes" > /dev/null; then
!       AC_DEFINE([NEED_PRINTF_DIRECTIVE_A], 1,
!         [Define if the vasnprintf implementation needs special code for
!          the 'a' and 'A' directives.])
!     fi
      gl_REPLACE_VASNPRINTF
    fi
  ])
--- 34,40 ----
        ;;
    esac
    if test $gl_cv_func_vasnprintf_posix = no; then
!     gl_PREREQ_VASNPRINTF_DIRECTIVE_A
      gl_REPLACE_VASNPRINTF
    fi
  ])
*** m4/vasnprintf.m4    7 Mar 2007 01:34:55 -0000       1.13
--- m4/vasnprintf.m4    23 Mar 2007 00:15:03 -0000
***************
*** 1,4 ****
! # vasnprintf.m4 serial 9
  dnl Copyright (C) 2002-2004, 2006-2007 Free Software Foundation, Inc.
  dnl This file is free software; the Free Software Foundation
  dnl gives unlimited permission to copy and/or distribute it,
--- 1,4 ----
! # vasnprintf.m4 serial 10
  dnl Copyright (C) 2002-2004, 2006-2007 Free Software Foundation, Inc.
  dnl This file is free software; the Free Software Foundation
  dnl gives unlimited permission to copy and/or distribute it,
***************
*** 62,67 ****
--- 62,79 ----
    AC_CHECK_FUNCS(snprintf wcslen)
  ])
  
+ # Extra prerequisites of lib/vasnprintf.c for supporting the 'a' directive.
+ AC_DEFUN([gl_PREREQ_VASNPRINTF_DIRECTIVE_A],
+ [
+   AC_REQUIRE([gl_PRINTF_DIRECTIVE_A])
+   if ! expr "$gl_cv_func_printf_directive_a" : ".*yes" > /dev/null; then
+     AC_DEFINE([NEED_PRINTF_DIRECTIVE_A], 1,
+       [Define if the vasnprintf implementation needs special code for
+        the 'a' and 'A' directives.])
+     AC_CHECK_FUNCS([nl_langinfo])
+   fi
+ ])
+ 
  # Prerequisites of lib/asnprintf.c.
  AC_DEFUN([gl_PREREQ_ASNPRINTF],
  [
*** m4/vasprintf-posix.m4       9 Mar 2007 01:24:32 -0000       1.3
--- m4/vasprintf-posix.m4       23 Mar 2007 00:15:03 -0000
***************
*** 1,4 ****
! # vasprintf-posix.m4 serial 2
  dnl Copyright (C) 2007 Free Software Foundation, Inc.
  dnl This file is free software; the Free Software Foundation
  dnl gives unlimited permission to copy and/or distribute it,
--- 1,4 ----
! # vasprintf-posix.m4 serial 3
  dnl Copyright (C) 2007 Free Software Foundation, Inc.
  dnl This file is free software; the Free Software Foundation
  dnl gives unlimited permission to copy and/or distribute it,
***************
*** 34,44 ****
        ;;
    esac
    if test $gl_cv_func_vasprintf_posix = no; then
!     if ! expr "$gl_cv_func_printf_directive_a" : ".*yes" > /dev/null; then
!       AC_DEFINE([NEED_PRINTF_DIRECTIVE_A], 1,
!         [Define if the vasnprintf implementation needs special code for
!          the 'a' and 'A' directives.])
!     fi
      gl_REPLACE_VASNPRINTF
      gl_REPLACE_VASPRINTF
    fi
--- 34,40 ----
        ;;
    esac
    if test $gl_cv_func_vasprintf_posix = no; then
!     gl_PREREQ_VASNPRINTF_DIRECTIVE_A
      gl_REPLACE_VASNPRINTF
      gl_REPLACE_VASPRINTF
    fi
*** m4/vfprintf-posix.m4        9 Mar 2007 02:40:14 -0000       1.1
--- m4/vfprintf-posix.m4        23 Mar 2007 00:15:03 -0000
***************
*** 1,4 ****
! # vfprintf-posix.m4 serial 1
  dnl Copyright (C) 2007 Free Software Foundation, Inc.
  dnl This file is free software; the Free Software Foundation
  dnl gives unlimited permission to copy and/or distribute it,
--- 1,4 ----
! # vfprintf-posix.m4 serial 2
  dnl Copyright (C) 2007 Free Software Foundation, Inc.
  dnl This file is free software; the Free Software Foundation
  dnl gives unlimited permission to copy and/or distribute it,
***************
*** 31,41 ****
        ;;
    esac
    if test $gl_cv_func_vfprintf_posix = no; then
!     if ! expr "$gl_cv_func_printf_directive_a" : ".*yes" > /dev/null; then
!       AC_DEFINE([NEED_PRINTF_DIRECTIVE_A], 1,
!         [Define if the vasnprintf implementation needs special code for
!          the 'a' and 'A' directives.])
!     fi
      gl_REPLACE_VASNPRINTF
      gl_REPLACE_VFPRINTF
    fi
--- 31,37 ----
        ;;
    esac
    if test $gl_cv_func_vfprintf_posix = no; then
!     gl_PREREQ_VASNPRINTF_DIRECTIVE_A
      gl_REPLACE_VASNPRINTF
      gl_REPLACE_VFPRINTF
    fi
*** m4/vsnprintf-posix.m4       9 Mar 2007 01:24:32 -0000       1.2
--- m4/vsnprintf-posix.m4       23 Mar 2007 00:15:03 -0000
***************
*** 1,4 ****
! # vsnprintf-posix.m4 serial 1
  dnl Copyright (C) 2007 Free Software Foundation, Inc.
  dnl This file is free software; the Free Software Foundation
  dnl gives unlimited permission to copy and/or distribute it,
--- 1,4 ----
! # vsnprintf-posix.m4 serial 2
  dnl Copyright (C) 2007 Free Software Foundation, Inc.
  dnl This file is free software; the Free Software Foundation
  dnl gives unlimited permission to copy and/or distribute it,
***************
*** 51,61 ****
      esac
    fi
    if test $gl_cv_func_vsnprintf_posix = no; then
!     if ! expr "$gl_cv_func_printf_directive_a" : ".*yes" > /dev/null; then
!       AC_DEFINE([NEED_PRINTF_DIRECTIVE_A], 1,
!         [Define if the vasnprintf implementation needs special code for
!          the 'a' and 'A' directives.])
!     fi
      gl_REPLACE_VASNPRINTF
      gl_REPLACE_VSNPRINTF
    fi
--- 51,57 ----
      esac
    fi
    if test $gl_cv_func_vsnprintf_posix = no; then
!     gl_PREREQ_VASNPRINTF_DIRECTIVE_A
      gl_REPLACE_VASNPRINTF
      gl_REPLACE_VSNPRINTF
    fi
*** m4/vsprintf-posix.m4        9 Mar 2007 01:24:32 -0000       1.2
--- m4/vsprintf-posix.m4        23 Mar 2007 00:15:03 -0000
***************
*** 1,4 ****
! # vsprintf-posix.m4 serial 1
  dnl Copyright (C) 2007 Free Software Foundation, Inc.
  dnl This file is free software; the Free Software Foundation
  dnl gives unlimited permission to copy and/or distribute it,
--- 1,4 ----
! # vsprintf-posix.m4 serial 2
  dnl Copyright (C) 2007 Free Software Foundation, Inc.
  dnl This file is free software; the Free Software Foundation
  dnl gives unlimited permission to copy and/or distribute it,
***************
*** 31,41 ****
        ;;
    esac
    if test $gl_cv_func_vsprintf_posix = no; then
!     if ! expr "$gl_cv_func_printf_directive_a" : ".*yes" > /dev/null; then
!       AC_DEFINE([NEED_PRINTF_DIRECTIVE_A], 1,
!         [Define if the vasnprintf implementation needs special code for
!          the 'a' and 'A' directives.])
!     fi
      gl_REPLACE_VASNPRINTF
      gl_REPLACE_VSPRINTF
    fi
--- 31,37 ----
        ;;
    esac
    if test $gl_cv_func_vsprintf_posix = no; then
!     gl_PREREQ_VASNPRINTF_DIRECTIVE_A
      gl_REPLACE_VASNPRINTF
      gl_REPLACE_VSPRINTF
    fi





reply via email to

[Prev in Thread] Current Thread [Next in Thread]