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>
14 +#include <sys/system_properties.h>
22 gtz->transitions = NULL;
27 +/* Android uses a 'persist.sys.timezone' system property for the
28 + * current timezone instead of a /etc/localtime file:
29 + * https://android.googlesource.com/platform/ndk/+/android-2.2_r1/docs/system/libc/OVERVIEW.TXT#67
31 + * There are no files under /usr/share/zoneinfo - instead a single
32 + * /system/usr/share/zoneinfo/tzdata file is used which contains all
33 + * files compiled together with the following tool:
34 + * https://android.googlesource.com/platform/system/timezone/+/master/zone_compactor/main/java/ZoneCompactor.java
37 +zone_info_android (const gchar *identifier)
39 + struct tzdata_header
42 + uint32_t index_offset;
43 + uint32_t data_offset;
44 + uint32_t zonetab_offset;
45 + } __attribute__((packed)) header;
47 + struct tzdata_index_entry
53 + } __attribute__((packed)) entry;
55 + char sys_timezone[PROP_VALUE_MAX];
58 + if (identifier == NULL)
60 + if (__system_property_get ("persist.sys.timezone", sys_timezone) < 1)
62 + g_warning ("__system_property_get(\"persist.sys.timezone\") failed");
65 + identifier = sys_timezone;
68 + tzdata_fd = TEMP_FAILURE_RETRY (open ("/system/usr/share/zoneinfo/tzdata", O_RDONLY));
71 + g_warning ("Failed opening tzdata");
75 + if (TEMP_FAILURE_RETRY (read (tzdata_fd, &header, sizeof(header)) < (ssize_t) sizeof (header)))
77 + g_warning ("Failed reading tzdata header");
81 + header.index_offset = htonl (header.index_offset);
82 + header.data_offset = htonl (header.data_offset);
84 + uint32_t current_offset = header.index_offset;
85 + while (current_offset < header.data_offset)
87 + if (TEMP_FAILURE_RETRY (read (tzdata_fd, &entry, sizeof(entry)) < (ssize_t) sizeof (entry)))
89 + g_warning ("Failed reading tzdata index entry");
93 + if (strcmp (entry.name, identifier) == 0)
95 + entry.offset = htonl (entry.offset);
96 + entry.length = htonl (entry.length);
97 + if (entry.length == 0)
99 + g_warning ("Invalid tzdata entry with length zero");
103 + if (TEMP_FAILURE_RETRY (lseek (tzdata_fd, header.data_offset + entry.offset, SEEK_SET) == -1))
105 + g_warning ("Failed seeking to tzdata entry");
109 + /* Use a reasonable but arbitrary max length of an entry. */
110 + if (entry.length > 65536)
112 + g_warning ("Too large tzdata entry length");
116 + guint8* data = g_malloc (entry.length);
117 + if (TEMP_FAILURE_RETRY (read (tzdata_fd, data, entry.length) < entry.length))
119 + g_warning ("Failed reading tzdata entry");
125 + return g_bytes_new_take (data, entry.length);
135 +#elif defined(G_OS_UNIX)
138 zone_info_unix (const gchar *identifier)
149 init_zone_from_iana_info (GTimeZone *gtz, GBytes *zoneinfo)
151 @@ -1387,7 +1496,11 @@
152 if (tz->t_info == NULL)
156 + GBytes *zoneinfo = zone_info_android (identifier);
158 GBytes *zoneinfo = zone_info_unix (identifier);
161 zone_for_constant_offset (tz, "UTC");