ASR_BASE
Change-Id: Icf3719cc0afe3eeb3edc7fa80a2eb5199ca9dda1
diff --git a/toolchain/musl/patches/110-read_timezone_from_fs.patch b/toolchain/musl/patches/110-read_timezone_from_fs.patch
new file mode 100644
index 0000000..c6d5d90
--- /dev/null
+++ b/toolchain/musl/patches/110-read_timezone_from_fs.patch
@@ -0,0 +1,97 @@
+--- a/src/time/__tz.c
++++ b/src/time/__tz.c
+@@ -5,6 +5,10 @@
+ #include <string.h>
+ #include <sys/mman.h>
+ #include <ctype.h>
++#include <unistd.h>
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <fcntl.h>
+ #include "libc.h"
+ #include "lock.h"
+ #include "fork_impl.h"
+@@ -123,6 +127,67 @@ static size_t zi_dotprod(const unsigned
+ return y;
+ }
+
++#define TZ_BUFLEN (2*TZNAME_MAX + 56)
++static char *read_TZ_file(char *buf)
++{
++ int r;
++ int fd;
++ char *p = NULL;
++
++ fd = open("/etc/TZ", O_RDONLY);
++ if (fd >= 0) {
++ /* Shorter, and does one fewer read syscall */
++ r = read(fd, buf, TZ_BUFLEN);
++ if (r < 0)
++ goto ERROR;
++ p = buf + r;
++
++ if ((p > buf) && (p[-1] == '\n')) { /* Must end with newline */
++ p[-1] = 0;
++ p = buf;
++ } else {
++ERROR:
++ p = NULL;
++ }
++ close(fd);
++ } else {
++ fd = open("/etc/localtime", O_RDONLY);
++ if (fd >= 0) {
++ r = read(fd, buf, TZ_BUFLEN);
++ if (r != TZ_BUFLEN
++ || strncmp(buf, "TZif", 4) != 0
++ || (unsigned char)buf[4] < 2
++ || lseek(fd, -TZ_BUFLEN, SEEK_END) < 0
++ ) {
++ goto ERROR;
++ }
++ /* tzfile.h from tzcode database says about TZif2+ files:
++ **
++ ** If tzh_version is '2' or greater, the above is followed by a second instance
++ ** of tzhead and a second instance of the data in which each coded transition
++ ** time uses 8 rather than 4 chars,
++ ** then a POSIX-TZ-environment-variable-style string for use in handling
++ ** instants after the last transition time stored in the file
++ ** (with nothing between the newlines if there is no POSIX representation for
++ ** such instants).
++ */
++ r = read(fd, buf, TZ_BUFLEN);
++ if (r <= 0 || buf[--r] != '\n')
++ goto ERROR;
++ buf[r] = 0;
++ while (r != 0) {
++ if (buf[--r] == '\n') {
++ p = buf + r + 1;
++ break;
++ }
++ } /* else ('\n' not found): p remains NULL */
++ close(fd);
++ }
++ }
++
++ return p;
++}
++
+ static void do_tzset()
+ {
+ char buf[NAME_MAX+25], *pathname=buf+24;
+@@ -131,8 +196,15 @@ static void do_tzset()
+ size_t i;
+ static const char search[] =
+ "/usr/share/zoneinfo/\0/share/zoneinfo/\0/etc/zoneinfo/\0";
++ char tzbuf[TZ_BUFLEN];
+
+ s = getenv("TZ");
++
++ /* if TZ is empty try to read it from /etc/TZ */
++ if (!s || !*s) {
++ s = read_TZ_file(tzbuf);
++ }
++
+ if (!s) s = "/etc/localtime";
+ if (!*s) s = __utc;
+