mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-05-01 11:36:51 +02:00
gtimezone: Split out fallback timezone identification for unix
When the TZ environment variable is not set, we get the local timezone identifier by reading specific files. We are going to need these identifiers earlier, so split this logic into its own function, in preparation for the next commit. Based on idea proposed by Sebastian Keller <skeller@gnome.org>.
This commit is contained in:
parent
8cbe2da75e
commit
7124b91e21
@ -438,46 +438,17 @@ zone_for_constant_offset (GTimeZone *gtz, const gchar *name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef G_OS_UNIX
|
#ifdef G_OS_UNIX
|
||||||
static GBytes*
|
static gchar *
|
||||||
zone_info_unix (const gchar *identifier,
|
zone_identifier_unix (void)
|
||||||
gchar **out_identifier)
|
|
||||||
{
|
{
|
||||||
gchar *filename;
|
|
||||||
GMappedFile *file = NULL;
|
|
||||||
GBytes *zoneinfo = NULL;
|
|
||||||
gchar *resolved_identifier = NULL;
|
gchar *resolved_identifier = NULL;
|
||||||
const gchar *tzdir;
|
|
||||||
|
|
||||||
tzdir = g_getenv ("TZDIR");
|
|
||||||
if (tzdir == NULL)
|
|
||||||
tzdir = "/usr/share/zoneinfo";
|
|
||||||
|
|
||||||
/* identifier can be a relative or absolute path name;
|
|
||||||
if relative, it is interpreted starting from /usr/share/zoneinfo
|
|
||||||
while the POSIX standard says it should start with :,
|
|
||||||
glibc allows both syntaxes, so we should too */
|
|
||||||
if (identifier != NULL)
|
|
||||||
{
|
|
||||||
resolved_identifier = g_strdup (identifier);
|
|
||||||
|
|
||||||
if (*identifier == ':')
|
|
||||||
identifier ++;
|
|
||||||
|
|
||||||
if (g_path_is_absolute (identifier))
|
|
||||||
filename = g_strdup (identifier);
|
|
||||||
else
|
|
||||||
filename = g_build_filename (tzdir, identifier, NULL);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
gsize prefix_len = 0;
|
gsize prefix_len = 0;
|
||||||
gchar *canonical_path = NULL;
|
gchar *canonical_path = NULL;
|
||||||
GError *read_link_err = NULL;
|
GError *read_link_err = NULL;
|
||||||
|
const gchar *tzdir;
|
||||||
filename = g_strdup ("/etc/localtime");
|
|
||||||
|
|
||||||
/* Resolve the actual timezone pointed to by /etc/localtime. */
|
/* Resolve the actual timezone pointed to by /etc/localtime. */
|
||||||
resolved_identifier = g_file_read_link (filename, &read_link_err);
|
resolved_identifier = g_file_read_link ("/etc/localtime", &read_link_err);
|
||||||
if (resolved_identifier == NULL)
|
if (resolved_identifier == NULL)
|
||||||
{
|
{
|
||||||
gboolean not_a_symlink = g_error_matches (read_link_err,
|
gboolean not_a_symlink = g_error_matches (read_link_err,
|
||||||
@ -512,6 +483,10 @@ zone_info_unix (const gchar *identifier,
|
|||||||
resolved_identifier = g_steal_pointer (&canonical_path);
|
resolved_identifier = g_steal_pointer (&canonical_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tzdir = g_getenv ("TZDIR");
|
||||||
|
if (tzdir == NULL)
|
||||||
|
tzdir = "/usr/share/zoneinfo";
|
||||||
|
|
||||||
/* Strip the prefix and slashes if possible. */
|
/* Strip the prefix and slashes if possible. */
|
||||||
if (g_str_has_prefix (resolved_identifier, tzdir))
|
if (g_str_has_prefix (resolved_identifier, tzdir))
|
||||||
{
|
{
|
||||||
@ -524,7 +499,51 @@ zone_info_unix (const gchar *identifier,
|
|||||||
memmove (resolved_identifier, resolved_identifier + prefix_len,
|
memmove (resolved_identifier, resolved_identifier + prefix_len,
|
||||||
strlen (resolved_identifier) - prefix_len + 1 /* nul terminator */);
|
strlen (resolved_identifier) - prefix_len + 1 /* nul terminator */);
|
||||||
|
|
||||||
|
g_assert (resolved_identifier != NULL);
|
||||||
|
|
||||||
|
out:
|
||||||
g_free (canonical_path);
|
g_free (canonical_path);
|
||||||
|
|
||||||
|
return resolved_identifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GBytes*
|
||||||
|
zone_info_unix (const gchar *identifier,
|
||||||
|
gchar **out_identifier)
|
||||||
|
{
|
||||||
|
gchar *filename = NULL;
|
||||||
|
GMappedFile *file = NULL;
|
||||||
|
GBytes *zoneinfo = NULL;
|
||||||
|
gchar *resolved_identifier = NULL;
|
||||||
|
const gchar *tzdir;
|
||||||
|
|
||||||
|
tzdir = g_getenv ("TZDIR");
|
||||||
|
if (tzdir == NULL)
|
||||||
|
tzdir = "/usr/share/zoneinfo";
|
||||||
|
|
||||||
|
/* identifier can be a relative or absolute path name;
|
||||||
|
if relative, it is interpreted starting from /usr/share/zoneinfo
|
||||||
|
while the POSIX standard says it should start with :,
|
||||||
|
glibc allows both syntaxes, so we should too */
|
||||||
|
if (identifier != NULL)
|
||||||
|
{
|
||||||
|
resolved_identifier = g_strdup (identifier);
|
||||||
|
|
||||||
|
if (*identifier == ':')
|
||||||
|
identifier ++;
|
||||||
|
|
||||||
|
if (g_path_is_absolute (identifier))
|
||||||
|
filename = g_strdup (identifier);
|
||||||
|
else
|
||||||
|
filename = g_build_filename (tzdir, identifier, NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
resolved_identifier = zone_identifier_unix ();
|
||||||
|
if (resolved_identifier == NULL)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
filename = g_strdup ("/etc/localtime");
|
||||||
}
|
}
|
||||||
|
|
||||||
file = g_mapped_file_new (filename, FALSE, NULL);
|
file = g_mapped_file_new (filename, FALSE, NULL);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user