|
@ -1,8 +1,8 @@ |
|
|
Patch submitted at https://bugzilla.gnome.org/show_bug.cgi?id=771304 |
|
|
Patch submitted at https://bugzilla.gnome.org/show_bug.cgi?id=771304 |
|
|
|
|
|
|
|
|
diff -u -r ../glib-2.48.2/glib/gtimezone.c ./glib/gtimezone.c
|
|
|
diff -u -r ../glib-2.54.2/glib/gtimezone.c ./glib/gtimezone.c
|
|
|
--- ../glib-2.48.2/glib/gtimezone.c 2016-08-17 12:07:29.000000000 -0400
|
|
|
--- ../glib-2.54.2/glib/gtimezone.c 2017-07-14 01:03:39.000000000 +0200
|
|
|
+++ ./glib/gtimezone.c 2016-09-12 16:52:41.864974630 -0400
|
|
|
+++ ./glib/gtimezone.c 2017-12-09 02:03:46.797229494 +0100
|
|
|
@@ -43,6 +43,13 @@
|
|
|
@@ -43,6 +43,13 @@
|
|
|
#include <windows.h> |
|
|
#include <windows.h> |
|
|
#endif |
|
|
#endif |
|
@ -17,87 +17,133 @@ diff -u -r ../glib-2.48.2/glib/gtimezone.c ./glib/gtimezone.c |
|
|
/** |
|
|
/** |
|
|
* SECTION:timezone |
|
|
* SECTION:timezone |
|
|
* @title: GTimeZone |
|
|
* @title: GTimeZone |
|
|
@@ -396,6 +400,75 @@
|
|
|
@@ -392,7 +399,105 @@
|
|
|
static GBytes* |
|
|
gtz->transitions = NULL; |
|
|
zone_info_unix (const gchar *identifier) |
|
|
} |
|
|
{ |
|
|
|
|
|
|
|
|
-#ifdef G_OS_UNIX
|
|
|
+#ifdef __ANDROID__
|
|
|
+#ifdef __ANDROID__
|
|
|
+ /* Android does not have /etc/localtime but uses a system property for the
|
|
|
+/* Android does not have /etc/localtime but uses a system property for the
|
|
|
+ the current timezone. There are no files under /usr/share/zoneinfo,
|
|
|
+ the current timezone. There are no files under /usr/share/zoneinfo,
|
|
|
+ instead a single /system/usr/share/zoneinfo/tzdata which are all zoneinfo
|
|
|
+ instead a single /system/usr/share/zoneinfo/tzdata which are all zoneinfo
|
|
|
+ files compiled together with the following tool:
|
|
|
+ files compiled together with the following tool:
|
|
|
+ https://android.googlesource.com/platform/external/icu/+/master/tools/ZoneCompactor.java */
|
|
|
+ https://android.googlesource.com/platform/external/icu/+/master/tools/ZoneCompactor.java */
|
|
|
+ struct tzdata_header {
|
|
|
+static GBytes*
|
|
|
+ char version[12];
|
|
|
+zone_info_android (const gchar *identifier)
|
|
|
+ uint32_t index_offset, data_offset, zonetab_offset;
|
|
|
+{
|
|
|
|
|
|
+ struct tzdata_header
|
|
|
|
|
|
+ {
|
|
|
|
|
|
+ char version[12];
|
|
|
|
|
|
+ uint32_t index_offset;
|
|
|
|
|
|
+ uint32_t data_offset;
|
|
|
|
|
|
+ uint32_t zonetab_offset;
|
|
|
+ } __attribute__((packed)) header;
|
|
|
+ } __attribute__((packed)) header;
|
|
|
+
|
|
|
+
|
|
|
+ struct tzdata_index_entry {
|
|
|
+ struct tzdata_index_entry
|
|
|
+ char name[40];
|
|
|
+ {
|
|
|
+ uint32_t offset, length, unused;
|
|
|
+ char name[40];
|
|
|
|
|
|
+ uint32_t offset;
|
|
|
|
|
|
+ uint32_t length;
|
|
|
|
|
|
+ uint32_t unused;
|
|
|
+ } __attribute__((packed)) entry;
|
|
|
+ } __attribute__((packed)) entry;
|
|
|
+
|
|
|
+
|
|
|
+ char sys_timezone[PROP_VALUE_MAX];
|
|
|
+ char sys_timezone[PROP_VALUE_MAX];
|
|
|
+ if (identifier == NULL) {
|
|
|
+
|
|
|
+ if (__system_property_get("persist.sys.timezone", sys_timezone) < 1) {
|
|
|
+ if (identifier == NULL)
|
|
|
+ g_warning("__system_property_get(\"persist.sys.timezone\") failed\n");
|
|
|
+ {
|
|
|
+ return NULL;
|
|
|
+ if (__system_property_get("persist.sys.timezone", sys_timezone) < 1)
|
|
|
|
|
|
+ {
|
|
|
|
|
|
+ g_warning("__system_property_get(\"persist.sys.timezone\") failed\n");
|
|
|
|
|
|
+ return NULL;
|
|
|
|
|
|
+ }
|
|
|
|
|
|
+ identifier = sys_timezone;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ identifier = sys_timezone;
|
|
|
+
|
|
|
|
|
|
+ int tzdata_fd = open("/system/usr/share/zoneinfo/tzdata", O_RDONLY);
|
|
|
|
|
|
+ if (tzdata_fd < 0)
|
|
|
|
|
|
+ {
|
|
|
|
|
|
+ g_warning("Failed opening tzdata");
|
|
|
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (identifier != NULL) {
|
|
|
|
|
|
+ int tzdata_fd = open("/system/usr/share/zoneinfo/tzdata", O_RDONLY);
|
|
|
|
|
|
+ if (tzdata_fd < 0) {
|
|
|
|
|
|
+ g_warning("Failed opening tzdata");
|
|
|
|
|
|
+ return NULL;
|
|
|
|
|
|
+ }
|
|
|
|
|
|
+ if (read(tzdata_fd, &header, sizeof(header)) < (ssize_t) sizeof(header)) {
|
|
|
|
|
|
+ g_warning("Failed reading tzdata header");
|
|
|
|
|
|
+ goto error;
|
|
|
|
|
|
+ }
|
|
|
|
|
|
+ header.index_offset = htonl(header.index_offset);
|
|
|
|
|
|
+ header.data_offset = htonl(header.data_offset);
|
|
|
|
|
|
+
|
|
|
+
|
|
|
+ uint32_t current_offset = header.index_offset;
|
|
|
+ if (read(tzdata_fd, &header, sizeof(header)) < (ssize_t) sizeof(header))
|
|
|
+ while (current_offset < header.data_offset) {
|
|
|
+ {
|
|
|
+ if (read(tzdata_fd, &entry, sizeof(entry)) < (ssize_t) sizeof(entry)) {
|
|
|
+ g_warning("Failed reading tzdata header");
|
|
|
|
|
|
+ goto error;
|
|
|
|
|
|
+ }
|
|
|
|
|
|
+
|
|
|
|
|
|
+ header.index_offset = htonl(header.index_offset);
|
|
|
|
|
|
+ header.data_offset = htonl(header.data_offset);
|
|
|
|
|
|
+
|
|
|
|
|
|
+ uint32_t current_offset = header.index_offset;
|
|
|
|
|
|
+ while (current_offset < header.data_offset)
|
|
|
|
|
|
+ {
|
|
|
|
|
|
+ if (read(tzdata_fd, &entry, sizeof(entry)) < (ssize_t) sizeof(entry))
|
|
|
|
|
|
+ {
|
|
|
+ g_warning("Failed reading tzdata index entry");
|
|
|
+ g_warning("Failed reading tzdata index entry");
|
|
|
+ goto error;
|
|
|
+ goto error;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (strcmp(entry.name, identifier) == 0) {
|
|
|
+
|
|
|
+ entry.offset = htonl(entry.offset);
|
|
|
+ if (strcmp(entry.name, identifier) == 0)
|
|
|
+ entry.length = htonl(entry.length);
|
|
|
+ {
|
|
|
+ if (entry.length == 0) {
|
|
|
+ entry.offset = htonl(entry.offset);
|
|
|
+ g_warning("Invalid tzdata entry with length zero");
|
|
|
+ entry.length = htonl(entry.length);
|
|
|
+ goto error;
|
|
|
+ if (entry.length == 0)
|
|
|
+ }
|
|
|
+ {
|
|
|
+ if (lseek(tzdata_fd, header.data_offset + entry.offset, SEEK_SET) == -1) {
|
|
|
+ g_warning("Invalid tzdata entry with length zero");
|
|
|
+ g_warning("Failed seeking to tzdata entry");
|
|
|
+ goto error;
|
|
|
+ goto error;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ guint8* data = g_malloc(entry.length);
|
|
|
+ if (lseek(tzdata_fd, header.data_offset + entry.offset, SEEK_SET) == -1)
|
|
|
+ if (read(tzdata_fd, data, entry.length) < entry.length) {
|
|
|
+ {
|
|
|
+ g_warning("Failed reading tzdata entry");
|
|
|
+ g_warning("Failed seeking to tzdata entry");
|
|
|
+ g_free(data);
|
|
|
+ goto error;
|
|
|
+ goto error;
|
|
|
+ }
|
|
|
|
|
|
+
|
|
|
|
|
|
+ guint8* data = g_malloc(entry.length);
|
|
|
|
|
|
+ if (read(tzdata_fd, data, entry.length) < entry.length)
|
|
|
|
|
|
+ {
|
|
|
|
|
|
+ g_warning("Failed reading tzdata entry");
|
|
|
|
|
|
+ g_free(data);
|
|
|
|
|
|
+ goto error;
|
|
|
|
|
|
+ }
|
|
|
|
|
|
+
|
|
|
|
|
|
+ close(tzdata_fd);
|
|
|
|
|
|
+ return g_bytes_new_take(data, entry.length);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ close(tzdata_fd);
|
|
|
|
|
|
+ return g_bytes_new_take(data, entry.length);
|
|
|
|
|
|
+ }
|
|
|
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
+
|
|
|
+error:
|
|
|
+error:
|
|
|
+ close(tzdata_fd);
|
|
|
+ close(tzdata_fd);
|
|
|
+ }
|
|
|
+
|
|
|
+ return NULL;
|
|
|
+ return NULL;
|
|
|
+#else
|
|
|
+}
|
|
|
gchar *filename; |
|
|
+
|
|
|
GMappedFile *file = NULL; |
|
|
+#elif defined(G_OS_UNIX)
|
|
|
GBytes *zoneinfo = NULL; |
|
|
+
|
|
|
@@ -434,6 +497,7 @@
|
|
|
static GBytes* |
|
|
} |
|
|
zone_info_unix (const gchar *identifier) |
|
|
g_free (filename); |
|
|
{ |
|
|
|
|
|
@@ -436,6 +541,10 @@
|
|
|
return zoneinfo; |
|
|
return zoneinfo; |
|
|
+#endif
|
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
+#endif
|
|
|
|
|
|
+
|
|
|
|
|
|
+#ifdef G_OS_UNIX
|
|
|
|
|
|
+
|
|
|
static void |
|
|
static void |
|
|
|
|
|
init_zone_from_iana_info (GTimeZone *gtz, GBytes *zoneinfo) |
|
|
|
|
|
{ |
|
|
|
|
|
@@ -1387,7 +1496,11 @@
|
|
|
|
|
|
if (tz->t_info == NULL) |
|
|
|
|
|
{ |
|
|
|
|
|
#ifdef G_OS_UNIX |
|
|
|
|
|
+# ifdef __ANDROID__
|
|
|
|
|
|
+ GBytes *zoneinfo = zone_info_android (identifier);
|
|
|
|
|
|
+# else
|
|
|
|
|
|
GBytes *zoneinfo = zone_info_unix (identifier); |
|
|
|
|
|
+# endif
|
|
|
|
|
|
if (!zoneinfo) |
|
|
|
|
|
zone_for_constant_offset (tz, "UTC"); |
|
|
|
|
|
else |
|
|