dnl Availability of various common functions (non-fatal if missing),
dnl and various less common threadsafe functions
AC_CHECK_FUNCS_ONCE([cfmakeraw geteuid getgid getgrnam_r getmntent_r \
- getpwuid_r getuid initgroups kill mmap posix_fallocate posix_memalign \
- regexec sched_getaffinity])
+ getpwuid_r getuid initgroups kill mmap newlocale posix_fallocate \
+ posix_memalign regexec sched_getaffinity])
dnl Availability of pthread functions (if missing, win32 threading is
dnl assumed). Because of $LIB_PTHREAD, we cannot use AC_CHECK_FUNCS_ONCE.
{
virJSONValuePtr val = NULL;
char *str;
- if (virAsprintf(&str, "%lf", data) < 0)
+ if (virDoubleToStr(&str, data) < 0)
return NULL;
val = virJSONValueNewNumber(str);
VIR_FREE(str);
#include <signal.h>
#include <termios.h>
#include <pty.h>
+#include <locale.h>
#if HAVE_LIBDEVMAPPER_H
# include <libdevmapper.h>
return -1;
}
+/* In case thread-safe locales are available */
+#if HAVE_NEWLOCALE
+
+static locale_t virLocale;
+
+static int
+virLocaleOnceInit(void)
+{
+ virLocale = newlocale(LC_ALL_MASK, "C", (locale_t)0);
+ if (!virLocale)
+ return -1;
+ return 0;
+}
+
+VIR_ONCE_GLOBAL_INIT(virLocale)
+#endif
+
+/**
+ * virDoubleToStr
+ *
+ * converts double to string with C locale (thread-safe).
+ *
+ * Returns -1 on error, size of the string otherwise.
+ */
+int
+virDoubleToStr(char **strp, double number)
+{
+ int ret = -1;
+
+#if HAVE_NEWLOCALE
+
+ locale_t old_loc;
+
+ if (virLocaleInitialize() < 0)
+ goto error;
+
+ old_loc = uselocale(virLocale);
+ ret = virAsprintf(strp, "%lf", number);
+ uselocale(old_loc);
+
+#else
+
+ char *radix, *tmp;
+ struct lconv *lc;
+
+ if ((ret = virVasprintf(strp, "%lf", number) < 0)
+ goto error;
+
+ lc = localeconv();
+ radix = lc->decimal_point;
+ tmp = strstr(*strp, radix);
+ if (tmp) {
+ *tmp = '.';
+ if (strlen(radix) > 1)
+ memmove(tmp + 1, tmp + strlen(radix), strlen(*strp) - (tmp - str));
+ }
+
+#endif /* HAVE_NEWLOCALE */
+ error:
+ return ret;
+}
+
const char *virEnumToString(const char *const*types,
unsigned int ntypes,
int type)
ATTRIBUTE_RETURN_CHECK;
# define virStrcpyStatic(dest, src) virStrcpy((dest), (src), sizeof(dest))
+int virDoubleToStr(char **strp, double number)
+ ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;
+
int virDiskNameToIndex(const char* str);
char *virIndexToDiskName(int idx, const char *prefix);