chiark / gitweb /
neovim: Update to latest version
[termux-packages] / packages / glib / glib-gtimezone.c.patch
1 diff -u -r ../glib-2.48.2/glib/gtimezone.c ./glib/gtimezone.c
2 --- ../glib-2.48.2/glib/gtimezone.c     2016-08-17 12:07:29.000000000 -0400
3 +++ ./glib/gtimezone.c  2016-09-12 16:52:41.864974630 -0400
4 @@ -43,6 +43,11 @@
5  #include <windows.h>
6  #endif
7  
8 +#ifdef __ANDROID__
9 +#include <fcntl.h>
10 +#include <sys/system_properties.h>
11 +#endif
12 +
13  /**
14   * SECTION:timezone
15   * @title: GTimeZone
16 @@ -396,6 +400,75 @@
17  static GBytes*
18  zone_info_unix (const gchar *identifier)
19  {
20 +#ifdef __ANDROID__
21 +  /* Android does not have /etc/localtime but uses a system property for the
22 +     the current timezone. There are no files under /usr/share/zoneinfo,
23 +     instead a single /system/usr/share/zoneinfo/tzdata which are all zoneinfo
24 +     files compiled together with the following tool:
25 +     https://android.googlesource.com/platform/external/icu/+/master/tools/ZoneCompactor.java */
26 +  struct tzdata_header {
27 +    char version[12];
28 +    uint32_t index_offset, data_offset, zonetab_offset;
29 +  } __attribute__((packed)) header;
30 +
31 +  struct tzdata_index_entry {
32 +    char name[40];
33 +    uint32_t offset, length, unused;
34 +  } __attribute__((packed)) entry;
35 +
36 +  if (identifier == NULL) {
37 +    char sys_timezone[PROP_VALUE_MAX];
38 +    if (__system_property_get("persist.sys.timezone", sys_timezone) < 1) {
39 +      g_warning("__system_property_get(\"persist.sys.timezone\") failed\n");
40 +      return NULL;
41 +    }
42 +    identifier = sys_timezone;
43 +  }
44 +  if (identifier != NULL) {
45 +    int tzdata_fd = open("/system/usr/share/zoneinfo/tzdata", O_RDONLY);
46 +    if (tzdata_fd < 0) {
47 +      g_warning("Failed opening tzdata");
48 +      return NULL;
49 +    }
50 +    if (read(tzdata_fd, &header, sizeof(header)) < (ssize_t) sizeof(header)) {
51 +      g_warning("Failed reading tzdata header");
52 +      goto error;
53 +    }
54 +    header.index_offset = htonl(header.index_offset);
55 +    header.data_offset = htonl(header.data_offset);
56 +
57 +    uint32_t current_offset = header.index_offset;
58 +    while (current_offset < header.data_offset) {
59 +      if (read(tzdata_fd, &entry, sizeof(entry)) < (ssize_t) sizeof(entry)) {
60 +        g_warning("Failed reading tzdata index entry");
61 +        goto error;
62 +      }
63 +      if (strcmp(entry.name, identifier) == 0) {
64 +        entry.offset = htonl(entry.offset);
65 +        entry.length = htonl(entry.length);
66 +        if (entry.length == 0) {
67 +          g_warning("Invalid tzdata entry with length zero");
68 +          goto error;
69 +        }
70 +        if (lseek(tzdata_fd, header.data_offset + entry.offset, SEEK_SET) == -1) {
71 +          g_warning("Failed seeking to tzdata entry");
72 +          goto error;
73 +        }
74 +        guint8* data = g_malloc(entry.length);
75 +        if (read(tzdata_fd, data, entry.length) < entry.length) {
76 +          g_warning("Failed reading tzdata entry");
77 +          g_free(data);
78 +          goto error;
79 +        }
80 +        close(tzdata_fd);
81 +        return g_bytes_new_take(data, entry.length);
82 +      }
83 +    }
84 +error:
85 +    close(tzdata_fd);
86 +  }
87 +  return NULL;
88 +#else
89    gchar *filename;
90    GMappedFile *file = NULL;
91    GBytes *zoneinfo = NULL;
92 @@ -434,6 +497,7 @@
93      }
94    g_free (filename);
95    return zoneinfo;
96 +#endif
97  }
98  
99  static void