Replace unsafe setlocale() use with uselocale()
setlocale() is not threadsafe except when used only to query the locale without changing it. Let's use uselocale() instead, which changes the locale only on the calling thread. Much better.
This commit is contained in:
parent
cb75ca664b
commit
a22da99aaf
4 changed files with 85 additions and 34 deletions
|
@ -18,6 +18,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <langinfo.h>
|
||||
#include <locale.h>
|
||||
#include <glib.h>
|
||||
|
@ -149,12 +150,22 @@ DateEndianess
|
|||
date_endian_get_for_lang (const char *lang,
|
||||
gboolean verbose)
|
||||
{
|
||||
const char *old_lang;
|
||||
locale_t locale;
|
||||
locale_t old_locale;
|
||||
DateEndianess endian;
|
||||
|
||||
old_lang = setlocale (LC_TIME, lang);
|
||||
locale = newlocale (LC_TIME_MASK, lang, (locale_t) 0);
|
||||
if (locale == (locale_t) 0)
|
||||
g_warning ("Failed to create locale %s: %s", lang, g_strerror (errno));
|
||||
else
|
||||
old_locale = uselocale (locale);
|
||||
|
||||
endian = date_endian_get_default (verbose);
|
||||
setlocale (LC_TIME, old_lang);
|
||||
|
||||
if (locale != (locale_t) 0) {
|
||||
uselocale (old_locale);
|
||||
freelocale (locale);
|
||||
}
|
||||
|
||||
return endian;
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <config.h>
|
||||
#include "cc-format-chooser.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <locale.h>
|
||||
#include <langinfo.h>
|
||||
#include <string.h>
|
||||
|
@ -66,48 +67,66 @@ display_date (GtkWidget *label, GDateTime *dt, const gchar *format)
|
|||
static void
|
||||
update_format_examples (CcFormatChooser *chooser)
|
||||
{
|
||||
g_autofree gchar *time_locale = NULL;
|
||||
g_autofree gchar *numeric_locale = NULL;
|
||||
g_autofree gchar *monetary_locale = NULL;
|
||||
g_autofree gchar *measurement_locale = NULL;
|
||||
g_autofree gchar *paper_locale = NULL;
|
||||
locale_t locale;
|
||||
locale_t old_locale;
|
||||
g_autoptr(GDateTime) dt = NULL;
|
||||
g_autofree gchar *s = NULL;
|
||||
const gchar *fmt;
|
||||
g_autoptr(GtkPaperSize) paper = NULL;
|
||||
|
||||
time_locale = g_strdup (setlocale (LC_TIME, NULL));
|
||||
setlocale (LC_TIME, chooser->region);
|
||||
locale = newlocale (LC_TIME_MASK, chooser->region, (locale_t) 0);
|
||||
if (locale == (locale_t) 0)
|
||||
g_warning ("Failed to create locale %s: %s", chooser->region, g_strerror (errno));
|
||||
else
|
||||
old_locale = uselocale (locale);
|
||||
|
||||
dt = g_date_time_new_now_local ();
|
||||
display_date (chooser->date_format_label, dt, "%x");
|
||||
display_date (chooser->time_format_label, dt, "%X");
|
||||
display_date (chooser->date_time_format_label, dt, "%c");
|
||||
|
||||
setlocale (LC_TIME, time_locale);
|
||||
if (locale != (locale_t) 0) {
|
||||
uselocale (old_locale);
|
||||
freelocale (locale);
|
||||
}
|
||||
|
||||
numeric_locale = g_strdup (setlocale (LC_NUMERIC, NULL));
|
||||
setlocale (LC_NUMERIC, chooser->region);
|
||||
locale = newlocale (LC_NUMERIC_MASK, chooser->region, (locale_t) 0);
|
||||
if (locale == (locale_t) 0)
|
||||
g_warning ("Failed to create locale %s: %s", chooser->region, g_strerror (errno));
|
||||
else
|
||||
old_locale = uselocale (locale);
|
||||
|
||||
s = g_strdup_printf ("%'.2f", 123456789.00);
|
||||
gtk_label_set_text (GTK_LABEL (chooser->number_format_label), s);
|
||||
|
||||
setlocale (LC_NUMERIC, numeric_locale);
|
||||
if (locale != (locale_t) 0) {
|
||||
uselocale (old_locale);
|
||||
freelocale (locale);
|
||||
}
|
||||
|
||||
#if 0
|
||||
monetary_locale = g_strdup (setlocale (LC_MONETARY, NULL));
|
||||
setlocale (LC_MONETARY, chooser->region);
|
||||
locale = newlocale (LC_MONETARY_MASK, chooser->region, (locale_t) 0);
|
||||
if (locale == (locale_t) 0)
|
||||
g_warning ("Failed to create locale %s: %s", chooser->region, g_strerror (errno));
|
||||
else
|
||||
old_locale = uselocale (locale);
|
||||
|
||||
num_info = localeconv ();
|
||||
if (num_info != NULL)
|
||||
gtk_label_set_text (GTK_LABEL (chooser->currency_format_label), num_info->currency_symbol);
|
||||
|
||||
setlocale (LC_MONETARY, monetary_locale);
|
||||
if (locale != (locale_t) 0) {
|
||||
uselocale (old_locale);
|
||||
freelocale (locale);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef LC_MEASUREMENT
|
||||
measurement_locale = g_strdup (setlocale (LC_MEASUREMENT, NULL));
|
||||
setlocale (LC_MEASUREMENT, chooser->region);
|
||||
locale = newlocale (LC_MEASUREMENT_MASK, chooser->region, (locale_t) 0);
|
||||
if (locale == (locale_t) 0)
|
||||
g_warning ("Failed to create locale %s: %s", chooser->region, g_strerror (errno));
|
||||
else
|
||||
old_locale = uselocale (locale);
|
||||
|
||||
fmt = nl_langinfo (_NL_MEASUREMENT_MEASUREMENT);
|
||||
if (fmt && *fmt == 2)
|
||||
|
@ -115,17 +134,26 @@ update_format_examples (CcFormatChooser *chooser)
|
|||
else
|
||||
gtk_label_set_text (GTK_LABEL (chooser->measurement_format_label), C_("measurement format", "Metric"));
|
||||
|
||||
setlocale (LC_MEASUREMENT, measurement_locale);
|
||||
if (locale != (locale_t) 0) {
|
||||
uselocale (old_locale);
|
||||
freelocale (locale);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef LC_PAPER
|
||||
paper_locale = g_strdup (setlocale (LC_PAPER, NULL));
|
||||
setlocale (LC_PAPER, chooser->region);
|
||||
locale = newlocale (LC_PAPER_MASK, chooser->region, (locale_t) 0);
|
||||
if (locale == (locale_t) 0)
|
||||
g_warning ("Failed to create locale %s: %s", chooser->region, g_strerror (errno));
|
||||
else
|
||||
old_locale = uselocale (locale);
|
||||
|
||||
paper = gtk_paper_size_new (gtk_paper_size_get_default ());
|
||||
gtk_label_set_text (GTK_LABEL (chooser->paper_format_label), gtk_paper_size_get_display_name (paper));
|
||||
|
||||
setlocale (LC_PAPER, paper_locale);
|
||||
if (locale != (locale_t) 0) {
|
||||
uselocale (old_locale);
|
||||
freelocale (locale);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <errno.h>
|
||||
#include <locale.h>
|
||||
#include <glib/gi18n.h>
|
||||
#include <gio/gio.h>
|
||||
|
@ -228,20 +229,26 @@ set_restart_notification_visible (CcRegionPanel *self,
|
|||
const gchar *locale,
|
||||
gboolean visible)
|
||||
{
|
||||
g_autofree gchar *current_locale = NULL;
|
||||
locale_t new_locale;
|
||||
locale_t current_locale;
|
||||
g_autoptr(GFile) file = NULL;
|
||||
g_autoptr(GFileOutputStream) output_stream = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
if (locale) {
|
||||
current_locale = g_strdup (setlocale (LC_MESSAGES, NULL));
|
||||
setlocale (LC_MESSAGES, locale);
|
||||
new_locale = newlocale (LC_MESSAGES_MASK, locale, (locale_t) 0);
|
||||
if (new_locale == (locale_t) 0)
|
||||
g_warning ("Failed to create locale %s: %s", locale, g_strerror (errno));
|
||||
else
|
||||
current_locale = uselocale (new_locale);
|
||||
}
|
||||
|
||||
gtk_revealer_set_reveal_child (self->restart_revealer, visible);
|
||||
|
||||
if (locale)
|
||||
setlocale (LC_MESSAGES, current_locale);
|
||||
if (locale && new_locale != (locale_t) 0) {
|
||||
uselocale (current_locale);
|
||||
freelocale (new_locale);
|
||||
}
|
||||
|
||||
file = get_needs_restart_file ();
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <locale.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib/gi18n.h>
|
||||
|
@ -954,18 +955,22 @@ restart_now (CcUserPanel *self)
|
|||
static void
|
||||
show_restart_notification (CcUserPanel *self, const gchar *locale)
|
||||
{
|
||||
gchar *current_locale;
|
||||
locale_t current_locale;
|
||||
locale_t new_locale;
|
||||
|
||||
if (locale) {
|
||||
current_locale = g_strdup (setlocale (LC_MESSAGES, NULL));
|
||||
setlocale (LC_MESSAGES, locale);
|
||||
new_locale = newlocale (LC_MESSAGES_MASK, locale, (locale_t) 0);
|
||||
if (new_locale == (locale_t) 0)
|
||||
g_warning ("Failed to create locale %s: %s", locale, g_strerror (errno));
|
||||
else
|
||||
current_locale = uselocale (new_locale);
|
||||
}
|
||||
|
||||
gtk_revealer_set_reveal_child (self->notification_revealer, TRUE);
|
||||
|
||||
if (locale) {
|
||||
setlocale (LC_MESSAGES, current_locale);
|
||||
g_free (current_locale);
|
||||
if (locale && new_locale != (locale_t) 0) {
|
||||
uselocale (current_locale);
|
||||
freelocale (new_locale);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue