Revert "Revert "Do not look for tzdata file in /data.""
This reverts commit 4e013233b85ad14b3e23dcbe15c1b7130ccce527.
Issue was in unexpected returned fd and errno value combination.
See comments in bionic.cpp and time_test.cpp.
Bug: 236967833
Fix: 236967833
Test: atest CtsBionicTestCases
Test: atest toybox-tests
Change-Id: I51b3e1527ff16b2a6ea4d6fedf8102019f7fd896
diff --git a/libc/tzcode/bionic.cpp b/libc/tzcode/bionic.cpp
index e134aaa..d2b5d80 100644
--- a/libc/tzcode/bionic.cpp
+++ b/libc/tzcode/bionic.cpp
@@ -190,6 +190,18 @@
// Give up now, and don't try fallback tzdata files. We don't log here
// because for all we know the given olson id was nonsense.
close(fd);
+ // This file descriptor (-1) is passed to localtime.c. In invalid fd case
+ // upstream passes errno value around methods and having 0 there will
+ // indicate that time zone was found and read successfully and localtime's
+ // internal state was properly initialized (which wasn't as we couldn't find
+ // requested time zone in the tzdata file).
+ // If we reached this point errno is unlikely to be touched. It is only
+ // close(fd) which can do it, but that is very unlikely to happen. And
+ // even if it happens we can't extract any useful insights from it.
+ // We are overriding it to ENOENT as it matches upstream expectations -
+ // time zone is absent in the tzdata file == there is no TZif file in
+ // /usr/share/zoneinfo.
+ errno = ENOENT;
return -1;
}
@@ -206,24 +218,14 @@
int __bionic_open_tzdata(const char* olson_id, int32_t* entry_length) {
int fd;
- // Try the three locations for the tzdata file in a strict order:
- // 1: The O-MR1 time zone updates via APK update mechanism. This is
- // tried first because it allows us to test that the time zone updates
- // via APK mechanism still works even on devices with the time zone
- // module.
- // TODO: remove this when those devices are no longer supported.
- // 2: The time zone data module which contains the main copy. This is the
+ // Try the two locations for the tzdata file in a strict order:
+ // 1: The time zone data module which contains the main copy. This is the
// common case for current devices.
- // 3: The ultimate fallback: the non-updatable copy in /system.
+ // 2: The ultimate fallback: the non-updatable copy in /system.
#if defined(__ANDROID__)
// On Android devices, bionic has to work even if exec takes place without
// environment variables set. So, all paths are hardcoded here.
-
- fd = __bionic_open_tzdata_path("/data/misc/zoneinfo/current/tzdata",
- olson_id, entry_length);
- if (fd >= -1) return fd;
-
fd = __bionic_open_tzdata_path("/apex/com.android.tzdata/etc/tz/tzdata",
olson_id, entry_length);
if (fd >= -1) return fd;
@@ -233,16 +235,10 @@
if (fd >= -1) return fd;
#else
// On the host, we don't expect the hard-coded locations above to exist, and
- // we're not worried about security so we trust $ANDROID_DATA,
- // $ANDROID_TZDATA_ROOT, and $ANDROID_ROOT to point us in the right direction
- // instead.
+ // we're not worried about security so we trust $ANDROID_TZDATA_ROOT, and
+ // $ANDROID_ROOT to point us in the right direction instead.
- char* path = make_path("ANDROID_DATA", "/misc/zoneinfo/current/tzdata");
- fd = __bionic_open_tzdata_path(path, olson_id, entry_length);
- free(path);
- if (fd >= -1) return fd;
-
- path = make_path("ANDROID_TZDATA_ROOT", "/etc/tz/tzdata");
+ char* path = make_path("ANDROID_TZDATA_ROOT", "/etc/tz/tzdata");
fd = __bionic_open_tzdata_path(path, olson_id, entry_length);
free(path);
if (fd >= -1) return fd;