1 Patch submitted at https://bugzilla.gnome.org/show_bug.cgi?id=771304
3 diff -u -r ../glib-2.54.2/glib/gtimezone.c ./glib/gtimezone.c
4 --- ../glib-2.54.2/glib/gtimezone.c 2017-07-14 01:03:39.000000000 +0200
5 +++ ./glib/gtimezone.c 2017-12-09 02:03:46.797229494 +0100
11 +#include <arpa/inet.h>
13 +#include <sys/system_properties.h>
21 gtz->transitions = NULL;
26 +/* Android does not have /etc/localtime but uses a system property for the
27 + the current timezone. There are no files under /usr/share/zoneinfo,
28 + instead a single /system/usr/share/zoneinfo/tzdata which are all zoneinfo
29 + files compiled together with the following tool:
30 + https://android.googlesource.com/platform/external/icu/+/master/tools/ZoneCompactor.java */
32 +zone_info_android (const gchar *identifier)
34 + struct tzdata_header
37 + uint32_t index_offset;
38 + uint32_t data_offset;
39 + uint32_t zonetab_offset;
40 + } __attribute__((packed)) header;
42 + struct tzdata_index_entry
48 + } __attribute__((packed)) entry;
50 + char sys_timezone[PROP_VALUE_MAX];
52 + if (identifier == NULL)
54 + if (__system_property_get("persist.sys.timezone", sys_timezone) < 1)
56 + g_warning("__system_property_get(\"persist.sys.timezone\") failed\n");
59 + identifier = sys_timezone;
62 + int tzdata_fd = open("/system/usr/share/zoneinfo/tzdata", O_RDONLY);
65 + g_warning("Failed opening tzdata");
69 + if (read(tzdata_fd, &header, sizeof(header)) < (ssize_t) sizeof(header))
71 + g_warning("Failed reading tzdata header");
75 + header.index_offset = htonl(header.index_offset);
76 + header.data_offset = htonl(header.data_offset);
78 + uint32_t current_offset = header.index_offset;
79 + while (current_offset < header.data_offset)
81 + if (read(tzdata_fd, &entry, sizeof(entry)) < (ssize_t) sizeof(entry))
83 + g_warning("Failed reading tzdata index entry");
87 + if (strcmp(entry.name, identifier) == 0)
89 + entry.offset = htonl(entry.offset);
90 + entry.length = htonl(entry.length);
91 + if (entry.length == 0)
93 + g_warning("Invalid tzdata entry with length zero");
97 + if (lseek(tzdata_fd, header.data_offset + entry.offset, SEEK_SET) == -1)
99 + g_warning("Failed seeking to tzdata entry");
103 + guint8* data = g_malloc(entry.length);
104 + if (read(tzdata_fd, data, entry.length) < entry.length)
106 + g_warning("Failed reading tzdata entry");
112 + return g_bytes_new_take(data, entry.length);
122 +#elif defined(G_OS_UNIX)
125 zone_info_unix (const gchar *identifier)
136 init_zone_from_iana_info (GTimeZone *gtz, GBytes *zoneinfo)
138 @@ -1387,7 +1496,11 @@
139 if (tz->t_info == NULL)
143 + GBytes *zoneinfo = zone_info_android (identifier);
145 GBytes *zoneinfo = zone_info_unix (identifier);
148 zone_for_constant_offset (tz, "UTC");