Merge "Simplify the implementation of get_nproc()."
diff --git a/libc/Android.bp b/libc/Android.bp
index 53db888..b7cb59d 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -927,22 +927,41 @@
"arch-x86/generic/string/wcscpy.c",
"arch-x86/generic/string/wmemcmp.c",
- "arch-x86/atom/string/sse2-memchr-atom.S",
- "arch-x86/atom/string/sse2-memrchr-atom.S",
- "arch-x86/atom/string/sse2-strchr-atom.S",
- "arch-x86/atom/string/sse2-strnlen-atom.S",
- "arch-x86/atom/string/sse2-strrchr-atom.S",
- "arch-x86/atom/string/sse2-wcschr-atom.S",
- "arch-x86/atom/string/sse2-wcsrchr-atom.S",
- "arch-x86/atom/string/sse2-wcslen-atom.S",
- "arch-x86/atom/string/sse2-wcscmp-atom.S",
- "arch-x86/silvermont/string/sse2-memmove-slm.S",
- "arch-x86/silvermont/string/sse2-memset-slm.S",
- "arch-x86/silvermont/string/sse2-stpcpy-slm.S",
- "arch-x86/silvermont/string/sse2-stpncpy-slm.S",
- "arch-x86/silvermont/string/sse2-strcpy-slm.S",
- "arch-x86/silvermont/string/sse2-strlen-slm.S",
- "arch-x86/silvermont/string/sse2-strncpy-slm.S",
+ "arch-x86/string/sse2-memchr-atom.S",
+ "arch-x86/string/sse2-memmove-slm.S",
+ "arch-x86/string/sse2-memrchr-atom.S",
+ "arch-x86/string/sse2-memset-atom.S",
+ "arch-x86/string/sse2-memset-slm.S",
+ "arch-x86/string/sse2-stpcpy-slm.S",
+ "arch-x86/string/sse2-stpncpy-slm.S",
+ "arch-x86/string/sse2-strchr-atom.S",
+ "arch-x86/string/sse2-strcpy-slm.S",
+ "arch-x86/string/sse2-strlen-slm.S",
+ "arch-x86/string/sse2-strncpy-slm.S",
+ "arch-x86/string/sse2-strnlen-atom.S",
+ "arch-x86/string/sse2-strrchr-atom.S",
+ "arch-x86/string/sse2-wcschr-atom.S",
+ "arch-x86/string/sse2-wcsrchr-atom.S",
+ "arch-x86/string/sse2-wcslen-atom.S",
+ "arch-x86/string/sse2-wcscmp-atom.S",
+ "arch-x86/string/sse2-strlen-atom.S",
+
+ "arch-x86/string/ssse3-memcmp-atom.S",
+ "arch-x86/string/ssse3-memmove-atom.S",
+ "arch-x86/string/ssse3-strcat-atom.S",
+ "arch-x86/string/ssse3-strcmp-atom.S",
+ "arch-x86/string/ssse3-strcpy-atom.S",
+ "arch-x86/string/ssse3-strlcat-atom.S",
+ "arch-x86/string/ssse3-strlcpy-atom.S",
+ "arch-x86/string/ssse3-strncat-atom.S",
+ "arch-x86/string/ssse3-strncmp-atom.S",
+ "arch-x86/string/ssse3-strncpy-atom.S",
+ "arch-x86/string/ssse3-wcscat-atom.S",
+ "arch-x86/string/ssse3-wcscpy-atom.S",
+ "arch-x86/string/ssse3-wmemcmp-atom.S",
+
+ "arch-x86/string/sse4-memcmp-slm.S",
+ "arch-x86/string/sse4-wmemcmp-slm.S",
"arch-x86/bionic/__bionic_clone.S",
"arch-x86/bionic/_exit_with_stack_teardown.S",
@@ -952,29 +971,6 @@
"arch-x86/bionic/syscall.S",
"arch-x86/bionic/vfork.S",
"arch-x86/bionic/__x86.get_pc_thunk.S",
-
- // ssse3 functions
- "arch-x86/atom/string/ssse3-strcat-atom.S",
- "arch-x86/atom/string/ssse3-strcmp-atom.S",
- "arch-x86/atom/string/ssse3-strlcat-atom.S",
- "arch-x86/atom/string/ssse3-strlcpy-atom.S",
- "arch-x86/atom/string/ssse3-strncat-atom.S",
- "arch-x86/atom/string/ssse3-strncmp-atom.S",
- "arch-x86/atom/string/ssse3-wcscat-atom.S",
- "arch-x86/atom/string/ssse3-wcscpy-atom.S",
-
- // sse4 functions
- "arch-x86/silvermont/string/sse4-memcmp-slm.S",
- "arch-x86/silvermont/string/sse4-wmemcmp-slm.S",
-
- // atom functions
- "arch-x86/atom/string/sse2-memset-atom.S",
- "arch-x86/atom/string/sse2-strlen-atom.S",
- "arch-x86/atom/string/ssse3-memcmp-atom.S",
- "arch-x86/atom/string/ssse3-memmove-atom.S",
- "arch-x86/atom/string/ssse3-strcpy-atom.S",
- "arch-x86/atom/string/ssse3-strncpy-atom.S",
- "arch-x86/atom/string/ssse3-wmemcmp-atom.S",
],
exclude_srcs: [
diff --git a/libc/arch-x86/atom/string/cache.h b/libc/arch-x86/atom/string/cache.h
deleted file mode 100644
index 823bb1e..0000000
--- a/libc/arch-x86/atom/string/cache.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
-Copyright (c) 2010, Intel Corporation
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
-
- * Neither the name of Intel Corporation nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-/* Values are optimized for Atom */
-#define SHARED_CACHE_SIZE (512*1024) /* Atom L2 Cache */
-#define DATA_CACHE_SIZE (24*1024) /* Atom L1 Data Cache */
-
-#define SHARED_CACHE_SIZE_HALF (SHARED_CACHE_SIZE / 2)
-#define DATA_CACHE_SIZE_HALF (DATA_CACHE_SIZE / 2)
diff --git a/libc/arch-x86/silvermont/string/cache.h b/libc/arch-x86/string/cache.h
similarity index 80%
rename from libc/arch-x86/silvermont/string/cache.h
rename to libc/arch-x86/string/cache.h
index c342b1c..33719a0 100644
--- a/libc/arch-x86/silvermont/string/cache.h
+++ b/libc/arch-x86/string/cache.h
@@ -28,9 +28,14 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/* Values are optimized for Silvermont */
-#define SHARED_CACHE_SIZE (1024*1024) /* Silvermont L2 Cache */
-#define DATA_CACHE_SIZE (24*1024) /* Silvermont L1 Data Cache */
+#ifdef FOR_ATOM
+#define SHARED_CACHE_SIZE (512 * 1024) /* Atom L2 Cache */
+#endif
+#ifdef FOR_SILVERMONT
+#define SHARED_CACHE_SIZE (1024 * 1024) /* Silvermont L2 Cache */
+#endif
-#define SHARED_CACHE_SIZE_HALF (SHARED_CACHE_SIZE / 2)
-#define DATA_CACHE_SIZE_HALF (DATA_CACHE_SIZE / 2)
+#define DATA_CACHE_SIZE (24 * 1024) /* Atom and Silvermont L1 Data Cache */
+
+#define SHARED_CACHE_SIZE_HALF (SHARED_CACHE_SIZE / 2)
+#define DATA_CACHE_SIZE_HALF (DATA_CACHE_SIZE / 2)
diff --git a/libc/arch-x86/atom/string/sse2-memchr-atom.S b/libc/arch-x86/string/sse2-memchr-atom.S
similarity index 100%
rename from libc/arch-x86/atom/string/sse2-memchr-atom.S
rename to libc/arch-x86/string/sse2-memchr-atom.S
diff --git a/libc/arch-x86/silvermont/string/sse2-memmove-slm.S b/libc/arch-x86/string/sse2-memmove-slm.S
similarity index 99%
rename from libc/arch-x86/silvermont/string/sse2-memmove-slm.S
rename to libc/arch-x86/string/sse2-memmove-slm.S
index da6456c..79b5d1b 100644
--- a/libc/arch-x86/silvermont/string/sse2-memmove-slm.S
+++ b/libc/arch-x86/string/sse2-memmove-slm.S
@@ -28,6 +28,7 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#define FOR_SILVERMONT
#include "cache.h"
#ifndef MEMMOVE
diff --git a/libc/arch-x86/atom/string/sse2-memrchr-atom.S b/libc/arch-x86/string/sse2-memrchr-atom.S
similarity index 100%
rename from libc/arch-x86/atom/string/sse2-memrchr-atom.S
rename to libc/arch-x86/string/sse2-memrchr-atom.S
diff --git a/libc/arch-x86/atom/string/sse2-memset-atom.S b/libc/arch-x86/string/sse2-memset-atom.S
similarity index 99%
rename from libc/arch-x86/atom/string/sse2-memset-atom.S
rename to libc/arch-x86/string/sse2-memset-atom.S
index e4cd038..320afec 100644
--- a/libc/arch-x86/atom/string/sse2-memset-atom.S
+++ b/libc/arch-x86/string/sse2-memset-atom.S
@@ -30,6 +30,7 @@
#include <private/bionic_asm.h>
+#define FOR_ATOM
#include "cache.h"
#ifndef L
diff --git a/libc/arch-x86/silvermont/string/sse2-memset-slm.S b/libc/arch-x86/string/sse2-memset-slm.S
similarity index 99%
rename from libc/arch-x86/silvermont/string/sse2-memset-slm.S
rename to libc/arch-x86/string/sse2-memset-slm.S
index b7633f5..5cff141 100644
--- a/libc/arch-x86/silvermont/string/sse2-memset-slm.S
+++ b/libc/arch-x86/string/sse2-memset-slm.S
@@ -30,6 +30,7 @@
#include <private/bionic_asm.h>
+#define FOR_SILVERMONT
#include "cache.h"
#ifndef L
diff --git a/libc/arch-x86/silvermont/string/sse2-stpcpy-slm.S b/libc/arch-x86/string/sse2-stpcpy-slm.S
similarity index 100%
rename from libc/arch-x86/silvermont/string/sse2-stpcpy-slm.S
rename to libc/arch-x86/string/sse2-stpcpy-slm.S
diff --git a/libc/arch-x86/silvermont/string/sse2-stpncpy-slm.S b/libc/arch-x86/string/sse2-stpncpy-slm.S
similarity index 100%
rename from libc/arch-x86/silvermont/string/sse2-stpncpy-slm.S
rename to libc/arch-x86/string/sse2-stpncpy-slm.S
diff --git a/libc/arch-x86/atom/string/sse2-strchr-atom.S b/libc/arch-x86/string/sse2-strchr-atom.S
similarity index 100%
rename from libc/arch-x86/atom/string/sse2-strchr-atom.S
rename to libc/arch-x86/string/sse2-strchr-atom.S
diff --git a/libc/arch-x86/silvermont/string/sse2-strcpy-slm.S b/libc/arch-x86/string/sse2-strcpy-slm.S
similarity index 100%
rename from libc/arch-x86/silvermont/string/sse2-strcpy-slm.S
rename to libc/arch-x86/string/sse2-strcpy-slm.S
diff --git a/libc/arch-x86/atom/string/sse2-strlen-atom.S b/libc/arch-x86/string/sse2-strlen-atom.S
similarity index 100%
rename from libc/arch-x86/atom/string/sse2-strlen-atom.S
rename to libc/arch-x86/string/sse2-strlen-atom.S
diff --git a/libc/arch-x86/silvermont/string/sse2-strlen-slm.S b/libc/arch-x86/string/sse2-strlen-slm.S
similarity index 100%
rename from libc/arch-x86/silvermont/string/sse2-strlen-slm.S
rename to libc/arch-x86/string/sse2-strlen-slm.S
diff --git a/libc/arch-x86/silvermont/string/sse2-strncpy-slm.S b/libc/arch-x86/string/sse2-strncpy-slm.S
similarity index 100%
rename from libc/arch-x86/silvermont/string/sse2-strncpy-slm.S
rename to libc/arch-x86/string/sse2-strncpy-slm.S
diff --git a/libc/arch-x86/atom/string/sse2-strnlen-atom.S b/libc/arch-x86/string/sse2-strnlen-atom.S
similarity index 100%
rename from libc/arch-x86/atom/string/sse2-strnlen-atom.S
rename to libc/arch-x86/string/sse2-strnlen-atom.S
diff --git a/libc/arch-x86/atom/string/sse2-strrchr-atom.S b/libc/arch-x86/string/sse2-strrchr-atom.S
similarity index 100%
rename from libc/arch-x86/atom/string/sse2-strrchr-atom.S
rename to libc/arch-x86/string/sse2-strrchr-atom.S
diff --git a/libc/arch-x86/atom/string/sse2-wcschr-atom.S b/libc/arch-x86/string/sse2-wcschr-atom.S
similarity index 100%
rename from libc/arch-x86/atom/string/sse2-wcschr-atom.S
rename to libc/arch-x86/string/sse2-wcschr-atom.S
diff --git a/libc/arch-x86/atom/string/sse2-wcscmp-atom.S b/libc/arch-x86/string/sse2-wcscmp-atom.S
similarity index 100%
rename from libc/arch-x86/atom/string/sse2-wcscmp-atom.S
rename to libc/arch-x86/string/sse2-wcscmp-atom.S
diff --git a/libc/arch-x86/atom/string/sse2-wcslen-atom.S b/libc/arch-x86/string/sse2-wcslen-atom.S
similarity index 100%
rename from libc/arch-x86/atom/string/sse2-wcslen-atom.S
rename to libc/arch-x86/string/sse2-wcslen-atom.S
diff --git a/libc/arch-x86/atom/string/sse2-wcsrchr-atom.S b/libc/arch-x86/string/sse2-wcsrchr-atom.S
similarity index 100%
rename from libc/arch-x86/atom/string/sse2-wcsrchr-atom.S
rename to libc/arch-x86/string/sse2-wcsrchr-atom.S
diff --git a/libc/arch-x86/silvermont/string/sse4-memcmp-slm.S b/libc/arch-x86/string/sse4-memcmp-slm.S
similarity index 100%
rename from libc/arch-x86/silvermont/string/sse4-memcmp-slm.S
rename to libc/arch-x86/string/sse4-memcmp-slm.S
diff --git a/libc/arch-x86/silvermont/string/sse4-wmemcmp-slm.S b/libc/arch-x86/string/sse4-wmemcmp-slm.S
similarity index 100%
rename from libc/arch-x86/silvermont/string/sse4-wmemcmp-slm.S
rename to libc/arch-x86/string/sse4-wmemcmp-slm.S
diff --git a/libc/arch-x86/atom/string/ssse3-memcmp-atom.S b/libc/arch-x86/string/ssse3-memcmp-atom.S
similarity index 100%
rename from libc/arch-x86/atom/string/ssse3-memcmp-atom.S
rename to libc/arch-x86/string/ssse3-memcmp-atom.S
diff --git a/libc/arch-x86/atom/string/ssse3-memcpy-atom.S b/libc/arch-x86/string/ssse3-memcpy-atom.S
similarity index 99%
rename from libc/arch-x86/atom/string/ssse3-memcpy-atom.S
rename to libc/arch-x86/string/ssse3-memcpy-atom.S
index 5532e2e..fe3082e 100644
--- a/libc/arch-x86/atom/string/ssse3-memcpy-atom.S
+++ b/libc/arch-x86/string/ssse3-memcpy-atom.S
@@ -28,6 +28,7 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#define FOR_ATOM
#include "cache.h"
#ifndef MEMCPY
diff --git a/libc/arch-x86/atom/string/ssse3-memmove-atom.S b/libc/arch-x86/string/ssse3-memmove-atom.S
similarity index 100%
rename from libc/arch-x86/atom/string/ssse3-memmove-atom.S
rename to libc/arch-x86/string/ssse3-memmove-atom.S
diff --git a/libc/arch-x86/atom/string/ssse3-strcat-atom.S b/libc/arch-x86/string/ssse3-strcat-atom.S
similarity index 100%
rename from libc/arch-x86/atom/string/ssse3-strcat-atom.S
rename to libc/arch-x86/string/ssse3-strcat-atom.S
diff --git a/libc/arch-x86/atom/string/ssse3-strcmp-atom.S b/libc/arch-x86/string/ssse3-strcmp-atom.S
similarity index 100%
rename from libc/arch-x86/atom/string/ssse3-strcmp-atom.S
rename to libc/arch-x86/string/ssse3-strcmp-atom.S
diff --git a/libc/arch-x86/atom/string/ssse3-strcpy-atom.S b/libc/arch-x86/string/ssse3-strcpy-atom.S
similarity index 100%
rename from libc/arch-x86/atom/string/ssse3-strcpy-atom.S
rename to libc/arch-x86/string/ssse3-strcpy-atom.S
diff --git a/libc/arch-x86/atom/string/ssse3-strlcat-atom.S b/libc/arch-x86/string/ssse3-strlcat-atom.S
similarity index 100%
rename from libc/arch-x86/atom/string/ssse3-strlcat-atom.S
rename to libc/arch-x86/string/ssse3-strlcat-atom.S
diff --git a/libc/arch-x86/atom/string/ssse3-strlcpy-atom.S b/libc/arch-x86/string/ssse3-strlcpy-atom.S
similarity index 100%
rename from libc/arch-x86/atom/string/ssse3-strlcpy-atom.S
rename to libc/arch-x86/string/ssse3-strlcpy-atom.S
diff --git a/libc/arch-x86/atom/string/ssse3-strncat-atom.S b/libc/arch-x86/string/ssse3-strncat-atom.S
similarity index 100%
rename from libc/arch-x86/atom/string/ssse3-strncat-atom.S
rename to libc/arch-x86/string/ssse3-strncat-atom.S
diff --git a/libc/arch-x86/atom/string/ssse3-strncmp-atom.S b/libc/arch-x86/string/ssse3-strncmp-atom.S
similarity index 100%
rename from libc/arch-x86/atom/string/ssse3-strncmp-atom.S
rename to libc/arch-x86/string/ssse3-strncmp-atom.S
diff --git a/libc/arch-x86/atom/string/ssse3-strncpy-atom.S b/libc/arch-x86/string/ssse3-strncpy-atom.S
similarity index 100%
rename from libc/arch-x86/atom/string/ssse3-strncpy-atom.S
rename to libc/arch-x86/string/ssse3-strncpy-atom.S
diff --git a/libc/arch-x86/atom/string/ssse3-wcscat-atom.S b/libc/arch-x86/string/ssse3-wcscat-atom.S
similarity index 100%
rename from libc/arch-x86/atom/string/ssse3-wcscat-atom.S
rename to libc/arch-x86/string/ssse3-wcscat-atom.S
diff --git a/libc/arch-x86/atom/string/ssse3-wcscpy-atom.S b/libc/arch-x86/string/ssse3-wcscpy-atom.S
similarity index 100%
rename from libc/arch-x86/atom/string/ssse3-wcscpy-atom.S
rename to libc/arch-x86/string/ssse3-wcscpy-atom.S
diff --git a/libc/arch-x86/atom/string/ssse3-wmemcmp-atom.S b/libc/arch-x86/string/ssse3-wmemcmp-atom.S
similarity index 100%
rename from libc/arch-x86/atom/string/ssse3-wmemcmp-atom.S
rename to libc/arch-x86/string/ssse3-wmemcmp-atom.S
diff --git a/libc/stdio/stdio.cpp b/libc/stdio/stdio.cpp
index 08df2eb..27813a6 100644
--- a/libc/stdio/stdio.cpp
+++ b/libc/stdio/stdio.cpp
@@ -1129,7 +1129,9 @@
// Read directly into the caller's buffer.
while (total > 0) {
- ssize_t bytes_read = (*fp->_read)(fp->_cookie, dst, total);
+ // The _read function pointer takes an int instead of a size_t.
+ int chunk_size = MIN(total, INT_MAX);
+ ssize_t bytes_read = (*fp->_read)(fp->_cookie, dst, chunk_size);
if (bytes_read <= 0) {
fp->_flags |= (bytes_read == 0) ? __SEOF : __SERR;
break;
diff --git a/libc/tzcode/strftime.c b/libc/tzcode/strftime.c
index 8c1b983..d04c5ba 100644
--- a/libc/tzcode/strftime.c
+++ b/libc/tzcode/strftime.c
@@ -190,6 +190,29 @@
return normal;
}
+// Android-added: fall back mechanism when TM_ZONE is not initialized.
+#ifdef TM_ZONE
+static const char* _safe_tm_zone(const struct tm* tm) {
+ const char* zone = tm->TM_ZONE;
+ if (!zone || !*zone) {
+ // "The value of tm_isdst shall be positive if Daylight Savings Time is
+ // in effect, 0 if Daylight Savings Time is not in effect, and negative
+ // if the information is not available."
+ if (tm->tm_isdst == 0) {
+ zone = tzname[0];
+ } else if (tm->tm_isdst > 0) {
+ zone = tzname[1];
+ }
+
+ // "Replaced by the timezone name or abbreviation, or by no bytes if no
+ // timezone information exists."
+ if (!zone || !*zone) zone = "";
+ }
+
+ return zone;
+}
+#endif
+
static char *
_fmt(const char *format, const struct tm *t, char *pt,
const char *ptlim, enum warn *warnp)
@@ -524,21 +547,7 @@
case 'Z':
#ifdef TM_ZONE
// BEGIN: Android-changed.
- {
- const char* zone = t->TM_ZONE;
- if (!zone || !*zone) {
- // "The value of tm_isdst shall be positive if Daylight Savings Time is
- // in effect, 0 if Daylight Savings Time is not in effect, and negative
- // if the information is not available."
- if (t->tm_isdst == 0) zone = tzname[0];
- else if (t->tm_isdst > 0) zone = tzname[1];
-
- // "Replaced by the timezone name or abbreviation, or by no bytes if no
- // timezone information exists."
- if (!zone || !*zone) zone = "";
- }
- pt = _add(zone, pt, ptlim, modifier);
- }
+ pt = _add(_safe_tm_zone(t), pt, ptlim, modifier);
// END: Android-changed.
#elif HAVE_TZNAME
if (t->tm_isdst >= 0)
@@ -599,7 +608,11 @@
negative = diff < 0;
if (diff == 0) {
#ifdef TM_ZONE
- negative = t->TM_ZONE[0] == '-';
+ // Android-changed: do not use TM_ZONE as it is as it may be null.
+ {
+ const char* zone = _safe_tm_zone(t);
+ negative = zone[0] == '-';
+ }
#else
negative = t->tm_isdst < 0;
# if HAVE_TZNAME
diff --git a/tests/stdio_test.cpp b/tests/stdio_test.cpp
index 87031f6..5bc6567 100644
--- a/tests/stdio_test.cpp
+++ b/tests/stdio_test.cpp
@@ -25,6 +25,7 @@
#include <sys/cdefs.h>
#include <sys/socket.h>
#include <sys/stat.h>
+#include <sys/sysinfo.h>
#include <sys/types.h>
#include <unistd.h>
#include <wchar.h>
@@ -2938,3 +2939,27 @@
fclose(fp);
}
+
+static int64_t GetTotalRamGiB() {
+ struct sysinfo si;
+ sysinfo(&si);
+ return (static_cast<int64_t>(si.totalram) * si.mem_unit) / 1024 / 1024 / 1024;
+}
+
+TEST(STDIO_TEST, fread_int_overflow) {
+ if (GetTotalRamGiB() <= 4) GTEST_SKIP() << "not enough memory";
+
+ const size_t too_big_for_an_int = 0x80000000ULL;
+ std::vector<char> buf(too_big_for_an_int);
+ std::unique_ptr<FILE, decltype(&fclose)> fp{fopen("/dev/zero", "re"), fclose};
+ ASSERT_EQ(too_big_for_an_int, fread(&buf[0], 1, too_big_for_an_int, fp.get()));
+}
+
+TEST(STDIO_TEST, fwrite_int_overflow) {
+ if (GetTotalRamGiB() <= 4) GTEST_SKIP() << "not enough memory";
+
+ const size_t too_big_for_an_int = 0x80000000ULL;
+ std::vector<char> buf(too_big_for_an_int);
+ std::unique_ptr<FILE, decltype(&fclose)> fp{fopen("/dev/null", "we"), fclose};
+ ASSERT_EQ(too_big_for_an_int, fwrite(&buf[0], 1, too_big_for_an_int, fp.get()));
+}
diff --git a/tests/time_test.cpp b/tests/time_test.cpp
index 898496d..40e5c6d 100644
--- a/tests/time_test.cpp
+++ b/tests/time_test.cpp
@@ -266,7 +266,7 @@
EXPECT_STREQ("-1", buf);
}
-TEST(time, strftime_null_tm_zone) {
+TEST(time, strftime_Z_null_tm_zone) {
// Netflix on Nexus Player wouldn't start (http://b/25170306).
struct tm t;
memset(&t, 0, sizeof(tm));
@@ -304,6 +304,86 @@
#endif
}
+// According to C language specification the only tm struct field needed to
+// find out replacement for %z and %Z in strftime is tm_isdst. Which is
+// wrong, as time zones change their standard offset and even DST savings.
+// tzcode deviates from C language specification and requires tm struct either
+// to be output of localtime-like functions or to be modified by mktime call
+// before passing to strftime. See tz mailing discussion for more details
+// https://mm.icann.org/pipermail/tz/2022-July/031674.html
+// But we are testing case when tm.tm_zone is null, which means that tm struct
+// is not coming from localtime and is neither modified by mktime. That's why
+// we are comparing against +0000, even though America/Los_Angeles never
+// observes it.
+TEST(time, strftime_z_null_tm_zone) {
+ char str[64];
+ struct tm tm = {.tm_year = 109, .tm_mon = 4, .tm_mday = 2, .tm_isdst = 0};
+
+ setenv("TZ", "America/Los_Angeles", 1);
+ tzset();
+
+ tm.tm_zone = NULL;
+
+ size_t result = strftime(str, sizeof(str), "%z", &tm);
+
+ EXPECT_EQ(5U, result);
+ EXPECT_STREQ("+0000", str);
+
+ tm.tm_isdst = 1;
+
+ result = strftime(str, sizeof(str), "%z", &tm);
+
+ EXPECT_EQ(5U, result);
+ EXPECT_STREQ("+0000", str);
+
+ setenv("TZ", "UTC", 1);
+ tzset();
+
+ tm.tm_isdst = 0;
+
+ result = strftime(str, sizeof(str), "%z", &tm);
+
+ EXPECT_EQ(5U, result);
+ EXPECT_STREQ("+0000", str);
+
+ tm.tm_isdst = 1;
+
+ result = strftime(str, sizeof(str), "%z", &tm);
+
+ EXPECT_EQ(5U, result);
+ EXPECT_STREQ("+0000", str);
+}
+
+TEST(time, strftime_z_Europe_Lisbon) {
+ char str[64];
+ // During 1992-1996 Europe/Lisbon standard offset was 1 hour.
+ // tm_isdst is not set as it will be overridden by mktime call anyway.
+ struct tm tm = {.tm_year = 1996 - 1900, .tm_mon = 2, .tm_mday = 13};
+
+ setenv("TZ", "Europe/Lisbon", 1);
+ tzset();
+
+ // tzcode's strftime implementation for %z relies on prior mktime call.
+ // At the moment of writing %z value is taken from tm_gmtoff. So without
+ // mktime call %z is replaced with +0000.
+ // See https://mm.icann.org/pipermail/tz/2022-July/031674.html
+ mktime(&tm);
+
+ size_t result = strftime(str, sizeof(str), "%z", &tm);
+
+ EXPECT_EQ(5U, result);
+ EXPECT_STREQ("+0100", str);
+
+ // Now standard offset is 0.
+ tm = {.tm_year = 2022 - 1900, .tm_mon = 2, .tm_mday = 13};
+
+ mktime(&tm);
+ result = strftime(str, sizeof(str), "%z", &tm);
+
+ EXPECT_EQ(5U, result);
+ EXPECT_STREQ("+0000", str);
+}
+
TEST(time, strftime_l) {
locale_t cloc = newlocale(LC_ALL, "C.UTF-8", nullptr);
locale_t old_locale = uselocale(cloc);