Merge "Move platform-private symbols out of libdl.so"
diff --git a/android-changes-for-ndk-developers.md b/android-changes-for-ndk-developers.md
index 1630db8..4c13bec 100644
--- a/android-changes-for-ndk-developers.md
+++ b/android-changes-for-ndk-developers.md
@@ -417,3 +417,17 @@
| No workaround | Works for static STL | Broken | Works |
| `-Wl,-z,nodelete` | Works for static STL | Works | Works |
| No `dlclose` | Works | Works | Works |
+
+## Use of IFUNC in libc (True for all API levels on devices running Q)
+
+Starting with Android Q (API level 29), libc uses
+[IFUNC](https://sourceware.org/glibc/wiki/GNU_IFUNC) functionality in
+the dynamic linker to choose optimized assembler routines at run time
+rather than at build time. This lets us use the same `libc.so` on all
+devices, and is similar to what other OSes already did. Because the zygote
+uses the C library, this decision is made long before we know what API
+level an app targets, so all code sees the new IFUNC-using C library.
+Most apps should be unaffected by this change, but apps that hook or try to
+detect hooking of C library functions might need to fix their code to cope
+with IFUNC relocations. The affected functions are from `<string.h>`, but
+may expand to include more functions (and more libraries) in future.
diff --git a/build/run-on-host.sh b/build/run-on-host.sh
new file mode 100644
index 0000000..c3a2751
--- /dev/null
+++ b/build/run-on-host.sh
@@ -0,0 +1,47 @@
+#!/bin/bash -e
+
+source ${ANDROID_BUILD_TOP}/build/envsetup.sh
+
+TARGET_ARCH=$(get_build_var TARGET_ARCH)
+TARGET_OUT=$(get_build_var TARGET_OUT)
+TARGET_OUT_EXECUTABLES=$(get_build_var TARGET_OUT_EXECUTABLES)
+TARGET_OUT_DATA=$(get_build_var TARGET_OUT_DATA)
+HOST_OS=$(get_build_var HOST_OS)
+HOST_ARCH=$(get_build_var HOST_ARCH)
+HOST_OUT=$(get_build_var HOST_OUT)
+
+function prepare()
+{
+ BITS=$1
+ shift
+
+ NATIVETEST=${TARGET_OUT_DATA}/nativetest
+ if [ "${BITS}" = 64 ]; then
+ NATIVETEST=${NATIVETEST}64
+ fi
+
+ if [ ${TARGET_ARCH} = arm -o ${TARGET_ARCH} = mips -o ${TARGET_ARCH} = x86 ]; then
+ LINKER=${TARGET_OUT_EXECUTABLES}/linker
+ else
+ LINKER="${TARGET_OUT_EXECUTABLES}/linker64 ${TARGET_OUT_EXECUTABLES}/linker"
+ fi
+
+ if [ ${TARGET_ARCH} = x86 -o ${TARGET_ARCH} = x86_64 ]; then
+ m -j ${LINKER} ${TARGET_OUT}/etc/hosts ${TARGET_OUT_EXECUTABLES}/sh $@
+
+ if [ ! -d /system ]; then
+ echo "Attempting to create /system";
+ sudo mkdir -p -m 0777 /system;
+ fi
+ (
+ cd ${ANDROID_BUILD_TOP}
+ mkdir -p ${TARGET_OUT_DATA}/local/tmp
+ ln -fs `realpath ${TARGET_OUT}/bin` /system/
+ ln -fs `realpath ${TARGET_OUT}/etc` /system/
+ ln -fs `realpath ${TARGET_OUT}/lib` /system/
+ if [ -d "${TARGET_OUT}/lib64" ]; then
+ ln -fs `realpath ${TARGET_OUT}/lib64` /system/;
+ fi
+ )
+ fi
+}
diff --git a/docs/status.md b/docs/status.md
index 85f9b60..d6a2f4c 100644
--- a/docs/status.md
+++ b/docs/status.md
@@ -45,10 +45,18 @@
* `getloadavg` (BSD/GNU extension in <stdlib.h>)
New libc behavior in Q (API level 29):
- * Whole printf family now supports the GNU `%m` extension, rather than a special-case hack in `syslog`
- * `popen` now always uses `O_CLOEXEC`, not just with the `e` extension
- * Bug fixes to handling of UTF-8 U+fffe/U+ffff and code points above U+10ffff
- * `aligned_alloc` correctly verifies that `size` is a multiple of `alignment`
+ * Whole printf family now supports the GNU `%m` extension, rather than a
+ special-case hack in `syslog`.
+ * `popen` now always uses `O_CLOEXEC`, not just with the `e` extension.
+ * Bug fixes to handling of UTF-8 U+fffe/U+ffff and code points above U+10ffff.
+ * `aligned_alloc` correctly verifies that `size` is a multiple of `alignment`.
+ * Using `%n` with the printf family is now reported as a FORTIFY failure.
+ Previous versions of Android would ignore the `%n` but not consume the
+ corresponding pointer argument, leading to obscure errors. The scanf family
+ is unchanged.
+ * Support in strptime for `%F`, `%G`, `%g`, `%P`, `%u`, `%V`, and `%v`.
+ (strftime already supported them all.)
+ * [fdsan](fdsan.md) detects common file descriptor errors at runtime.
New libc functions in P (API level 28):
* `aligned_alloc`
@@ -69,9 +77,13 @@
* `syncfs`
New libc behavior in P (API level 28):
- * `%C` and `%S` support in the printf family (previously only the wprintf family supported these)
- * `%mc`/`%ms`/`%m[` support in the scanf family
- * `%s` support in strptime (strftime already supported it)
+ * `%C` and `%S` support in the printf family (previously only the wprintf family supported these).
+ * `%mc`/`%ms`/`%m[` support in the scanf family.
+ * `%s` support in strptime (strftime already supported it).
+ * Using a `pthread_mutex_t` after it's been destroyed will be detected at
+ runtime and reported as a FORTIFY failure.
+ * Passing a null `FILE*` or `DIR*` to libc is now detected at runtime and
+ reported as a FORTIFY failure.
New libc functions in O (API level 26):
* `sendto` FORTIFY support
@@ -96,6 +108,11 @@
* `strtod_l`/`strtof_l`/`strtol_l`/`strtoul_l`
* <wctype.h> `towctrans`/`towctrans_l`/`wctrans`/`wctrans_l`
+New libc behavior in O (API level 26):
+ * Passing an invalid `pthread_t` to libc is now detected at runtime and
+ reported as a FORTIFY failure. Most commonly this is a result of confusing
+ `pthread_t` and `pid_t`.
+
New libc functions in N (API level 24):
* more FORTIFY support functions (`fread`/`fwrite`/`getcwd`/`pwrite`/`write`)
* all remaining `_FILE_OFFSET_BITS=64` functions, completing `_FILE_OFFSET_BITS=64` support in bionic (8)
@@ -108,6 +125,9 @@
* GNU extensions `fileno_unlocked`/`strchrnul`
* 32-bit `prlimit`
+New libc behavior in N (API level 24):
+ * `sem_wait` now returns EINTR when interrupted by a signal.
+
New libc functions in M (API level 23):
* <dirent.h> `telldir`, `seekdir`.
* <malloc.h> `malloc_info`.
diff --git a/libc/Android.bp b/libc/Android.bp
index a27b1ce..182e8f7 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -77,14 +77,6 @@
native_coverage: false,
recovery_available: true,
- arch: {
- x86: {
- no_libcrt: true,
- },
- x86_64: {
- no_libcrt: true,
- },
- },
// lld complains about duplicate symbols in libcrt and libgcc. Suppress the
// warning since this is intended right now.
ldflags: ["-Wl,-z,muldefs"],
diff --git a/libc/arch-x86/dynamic_function_dispatch.cpp b/libc/arch-x86/dynamic_function_dispatch.cpp
index 6624385..70f4b3e 100644
--- a/libc/arch-x86/dynamic_function_dispatch.cpp
+++ b/libc/arch-x86/dynamic_function_dispatch.cpp
@@ -30,33 +30,6 @@
extern "C" {
-struct __processor_model {
- unsigned int __cpu_vendor;
- unsigned int __cpu_type;
- unsigned int __cpu_subtype;
- unsigned int __cpu_features[1];
-};
-
-__attribute__((visibility("hidden")))
-extern struct __processor_model __cpu_model;
-
-// These definitions have to match the values in
-// llvm/include/llvm/Support/X86TargetParser.def
-static constexpr int SSSE3 = 6;
-static constexpr int SSE4_1 = 7;
-static constexpr int ATOM = 1;
-
-// __builtin_cpu_supports and __builtin_cpu_is can not be used here. They
-// don't access __cpu_model directly but use GOT.
-// See https://reviews.llvm.org/D53850
-static bool cpu_supports(unsigned int feature) {
- return (__cpu_model.__cpu_features[0] & (1U << feature)) != 0;
-}
-
-static bool cpu_is(unsigned int type) {
- return (__cpu_model.__cpu_type == type);
-}
-
#define DEFINE_IFUNC_FOR(name) \
name##_func name __attribute__((ifunc(#name "_resolver"))); \
__attribute__((visibility("hidden"))) \
@@ -74,29 +47,29 @@
typedef int memcmp_func(const void* __lhs, const void* __rhs, size_t __n);
DEFINE_IFUNC_FOR(memcmp) {
__builtin_cpu_init();
- if (cpu_is(ATOM)) RETURN_FUNC(memcmp_func, memcmp_atom);
- if (cpu_supports(SSE4_1)) RETURN_FUNC(memcmp_func, memcmp_sse4);
+ if (__builtin_cpu_is("atom")) RETURN_FUNC(memcmp_func, memcmp_atom);
+ if (__builtin_cpu_supports("sse4.1")) RETURN_FUNC(memcmp_func, memcmp_sse4);
RETURN_FUNC(memcmp_func, memcmp_generic);
}
typedef void* memset_func(void* __dst, int __ch, size_t __n);
DEFINE_IFUNC_FOR(memset) {
__builtin_cpu_init();
- if (cpu_is(ATOM)) RETURN_FUNC(memset_func, memset_atom);
+ if (__builtin_cpu_is("atom")) RETURN_FUNC(memset_func, memset_atom);
RETURN_FUNC(memset_func, memset_generic);
}
typedef void* __memset_chk_func(void *s, int c, size_t n, size_t n2);
DEFINE_IFUNC_FOR(__memset_chk) {
__builtin_cpu_init();
- if (cpu_is(ATOM)) RETURN_FUNC(__memset_chk_func, __memset_chk_atom);
+ if (__builtin_cpu_is("atom")) RETURN_FUNC(__memset_chk_func, __memset_chk_atom);
RETURN_FUNC(__memset_chk_func, __memset_chk_generic);
}
typedef void* memmove_func(void* __dst, const void* __src, size_t __n);
DEFINE_IFUNC_FOR(memmove) {
__builtin_cpu_init();
- if (cpu_is(ATOM)) RETURN_FUNC(memmove_func, memmove_atom);
+ if (__builtin_cpu_is("atom")) RETURN_FUNC(memmove_func, memmove_atom);
RETURN_FUNC(memmove_func, memmove_generic);
}
@@ -108,85 +81,85 @@
typedef char* strcpy_func(char* __dst, const char* __src);
DEFINE_IFUNC_FOR(strcpy) {
__builtin_cpu_init();
- if (cpu_is(ATOM)) RETURN_FUNC(strcpy_func, strcpy_atom);
+ if (__builtin_cpu_is("atom")) RETURN_FUNC(strcpy_func, strcpy_atom);
RETURN_FUNC(strcpy_func, strcpy_generic);
}
typedef char* strncpy_func(char* __dst, const char* __src, size_t __n);
DEFINE_IFUNC_FOR(strncpy) {
__builtin_cpu_init();
- if (cpu_is(ATOM)) RETURN_FUNC(strncpy_func, strncpy_atom);
+ if (__builtin_cpu_is("atom")) RETURN_FUNC(strncpy_func, strncpy_atom);
RETURN_FUNC(strncpy_func, strncpy_generic);
}
typedef size_t strlen_func(const char* __s);
DEFINE_IFUNC_FOR(strlen) {
__builtin_cpu_init();
- if (cpu_is(ATOM)) RETURN_FUNC(strlen_func, strlen_atom);
+ if (__builtin_cpu_is("atom")) RETURN_FUNC(strlen_func, strlen_atom);
RETURN_FUNC(strlen_func, strlen_generic);
}
typedef int wmemcmp_func(const wchar_t* __lhs, const wchar_t* __rhs, size_t __n);
DEFINE_IFUNC_FOR(wmemcmp) {
__builtin_cpu_init();
- if (cpu_supports(SSE4_1)) RETURN_FUNC(wmemcmp_func, wmemcmp_sse4);
- if (cpu_is(ATOM)) RETURN_FUNC(wmemcmp_func, wmemcmp_atom);
+ if (__builtin_cpu_supports("sse4.1")) RETURN_FUNC(wmemcmp_func, wmemcmp_sse4);
+ if (__builtin_cpu_is("atom")) RETURN_FUNC(wmemcmp_func, wmemcmp_atom);
RETURN_FUNC(wmemcmp_func, wmemcmp_freebsd);
}
typedef int strcmp_func(const char* __lhs, const char* __rhs);
DEFINE_IFUNC_FOR(strcmp) {
__builtin_cpu_init();
- if (cpu_supports(SSSE3)) RETURN_FUNC(strcmp_func, strcmp_ssse3);
+ if (__builtin_cpu_supports("ssse3")) RETURN_FUNC(strcmp_func, strcmp_ssse3);
RETURN_FUNC(strcmp_func, strcmp_generic);
}
typedef int strncmp_func(const char* __lhs, const char* __rhs, size_t __n);
DEFINE_IFUNC_FOR(strncmp) {
__builtin_cpu_init();
- if (cpu_supports(SSSE3)) RETURN_FUNC(strncmp_func, strncmp_ssse3);
+ if (__builtin_cpu_supports("ssse3")) RETURN_FUNC(strncmp_func, strncmp_ssse3);
RETURN_FUNC(strncmp_func, strncmp_generic);
}
typedef char* strcat_func(char* __dst, const char* __src);
DEFINE_IFUNC_FOR(strcat) {
__builtin_cpu_init();
- if (cpu_supports(SSSE3)) RETURN_FUNC(strcat_func, strcat_ssse3);
+ if (__builtin_cpu_supports("ssse3")) RETURN_FUNC(strcat_func, strcat_ssse3);
RETURN_FUNC(strcat_func, strcat_generic);
}
typedef char* strncat_func(char* __dst, const char* __src, size_t __n);
DEFINE_IFUNC_FOR(strncat) {
__builtin_cpu_init();
- if (cpu_supports(SSSE3)) RETURN_FUNC(strncat_func, strncat_ssse3);
+ if (__builtin_cpu_supports("ssse3")) RETURN_FUNC(strncat_func, strncat_ssse3);
RETURN_FUNC(strncat_func, strncat_openbsd);
}
typedef size_t strlcat_func(char *dst, const char *src, size_t dsize);
DEFINE_IFUNC_FOR(strlcat) {
__builtin_cpu_init();
- if (cpu_supports(SSSE3)) RETURN_FUNC(strlcat_func, strlcat_ssse3);
+ if (__builtin_cpu_supports("ssse3")) RETURN_FUNC(strlcat_func, strlcat_ssse3);
RETURN_FUNC(strlcat_func, strlcat_openbsd);
}
typedef size_t strlcpy_func(char *dst, const char *src, size_t dsize);
DEFINE_IFUNC_FOR(strlcpy) {
__builtin_cpu_init();
- if (cpu_supports(SSSE3)) RETURN_FUNC(strlcpy_func, strlcpy_ssse3);
+ if (__builtin_cpu_supports("ssse3")) RETURN_FUNC(strlcpy_func, strlcpy_ssse3);
RETURN_FUNC(strlcpy_func, strlcpy_openbsd);
}
typedef wchar_t* wcscat_func(wchar_t *s1, const wchar_t *s2);
DEFINE_IFUNC_FOR(wcscat) {
__builtin_cpu_init();
- if (cpu_supports(SSSE3)) RETURN_FUNC(wcscat_func, wcscat_ssse3);
+ if (__builtin_cpu_supports("ssse3")) RETURN_FUNC(wcscat_func, wcscat_ssse3);
RETURN_FUNC(wcscat_func, wcscat_freebsd);
}
typedef wchar_t* wcscpy_func(wchar_t *s1, const wchar_t *s2);
DEFINE_IFUNC_FOR(wcscpy) {
__builtin_cpu_init();
- if (cpu_supports(SSSE3)) RETURN_FUNC(wcscpy_func, wcscpy_ssse3);
+ if (__builtin_cpu_supports("ssse3")) RETURN_FUNC(wcscpy_func, wcscpy_ssse3);
RETURN_FUNC(wcscpy_func, wcscpy_freebsd);
}
diff --git a/libc/bionic/__bionic_get_shell_path.cpp b/libc/bionic/__bionic_get_shell_path.cpp
index 1352815..7aeed18 100644
--- a/libc/bionic/__bionic_get_shell_path.cpp
+++ b/libc/bionic/__bionic_get_shell_path.cpp
@@ -26,6 +26,8 @@
* SUCH DAMAGE.
*/
+#include "private/__bionic_get_shell_path.h"
+
#include <errno.h>
#include <string.h>
#include <sys/cdefs.h>
@@ -51,7 +53,7 @@
return "/system/bin/sh";
}
-__LIBC_HIDDEN__ extern "C" const char* __bionic_get_shell_path() {
+const char* __bionic_get_shell_path() {
static const char* sh_path = init_sh_path();
return sh_path;
}
diff --git a/libc/bionic/android_set_abort_message.cpp b/libc/bionic/android_set_abort_message.cpp
index 56e6771..2ea12ee 100644
--- a/libc/bionic/android_set_abort_message.cpp
+++ b/libc/bionic/android_set_abort_message.cpp
@@ -33,6 +33,7 @@
#include <stddef.h>
#include <string.h>
#include <sys/mman.h>
+#include <sys/prctl.h>
#include "private/bionic_defs.h"
#include "private/bionic_globals.h"
@@ -82,6 +83,10 @@
return;
}
+ // Name the abort message mapping to make it easier for tools to find the
+ // mapping.
+ prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, map, size, "abort message");
+
magic_abort_msg_t* new_magic_abort_message = reinterpret_cast<magic_abort_msg_t*>(map);
fill_abort_message_magic(new_magic_abort_message);
new_magic_abort_message->msg.size = size;
diff --git a/libc/bionic/exec.cpp b/libc/bionic/exec.cpp
index 1cf3a58..3309585 100644
--- a/libc/bionic/exec.cpp
+++ b/libc/bionic/exec.cpp
@@ -39,6 +39,7 @@
#include <string.h>
#include <unistd.h>
+#include "private/__bionic_get_shell_path.h"
#include "private/FdPath.h"
extern "C" char** environ;
@@ -111,7 +112,7 @@
script_argv[0] = "sh";
script_argv[1] = buf;
memcpy(script_argv + 2, argv + 1, arg_count * sizeof(char*));
- return execve(_PATH_BSHELL, const_cast<char**>(script_argv), envp);
+ return execve(__bionic_get_shell_path(), const_cast<char**>(script_argv), envp);
}
int execvpe(const char* name, char* const* argv, char* const* envp) {
diff --git a/libc/bionic/malloc_limit.cpp b/libc/bionic/malloc_limit.cpp
index 69a8f89..b42865b 100644
--- a/libc/bionic/malloc_limit.cpp
+++ b/libc/bionic/malloc_limit.cpp
@@ -275,7 +275,7 @@
// being called, allow up to five ms for the signal handler to complete
// before failing.
bool enabled = false;
- size_t num_tries = 10;
+ size_t num_tries = 20;
while (true) {
if (!atomic_exchange(&gGlobalsMutating, true)) {
__libc_globals.mutate([](libc_globals* globals) {
diff --git a/libc/bionic/system.cpp b/libc/bionic/system.cpp
index 7411ae5..950f05c 100644
--- a/libc/bionic/system.cpp
+++ b/libc/bionic/system.cpp
@@ -27,12 +27,12 @@
*/
#include <errno.h>
-#include <paths.h>
#include <stdlib.h>
#include <spawn.h>
#include <sys/wait.h>
#include <unistd.h>
+#include "private/__bionic_get_shell_path.h"
#include "private/ScopedSignalBlocker.h"
#include "private/ScopedSignalHandler.h"
@@ -58,7 +58,7 @@
const char* argv[] = { "sh", "-c", command, nullptr };
pid_t child;
- if ((errno = posix_spawn(&child, _PATH_BSHELL, nullptr, &attributes,
+ if ((errno = posix_spawn(&child, __bionic_get_shell_path(), nullptr, &attributes,
const_cast<char**>(argv), environ)) != 0) {
return -1;
}
diff --git a/libc/include/android/fdsan.h b/libc/include/android/fdsan.h
index d71e6d4..1169ed0 100644
--- a/libc/include/android/fdsan.h
+++ b/libc/include/android/fdsan.h
@@ -149,19 +149,19 @@
*
* Returns 0 for untagged and invalid file descriptors.
*/
-uint64_t android_fdsan_get_owner_tag(int fd);
+uint64_t android_fdsan_get_owner_tag(int fd) __INTRODUCED_IN(29);
/*
* Get an owner tag's string representation.
*
* The return value points to memory with static lifetime, do not attempt to modify it.
*/
-const char* android_fdsan_get_tag_type(uint64_t tag);
+const char* android_fdsan_get_tag_type(uint64_t tag) __INTRODUCED_IN(29);
/*
* Get an owner tag's value, with the type masked off.
*/
-uint64_t android_fdsan_get_tag_value(uint64_t tag);
+uint64_t android_fdsan_get_tag_value(uint64_t tag) __INTRODUCED_IN(29);
enum android_fdsan_error_level {
// No errors.
diff --git a/libc/include/bits/get_device_api_level_inlines.h b/libc/include/bits/get_device_api_level_inlines.h
index 9c6e243..d14eb2c 100644
--- a/libc/include/bits/get_device_api_level_inlines.h
+++ b/libc/include/bits/get_device_api_level_inlines.h
@@ -28,11 +28,9 @@
#pragma once
-#include <sys/cdefs.h>
+#if defined(__BIONIC_GET_DEVICE_API_LEVEL_INLINE)
-#if !defined(__BIONIC_GET_DEVICE_API_LEVEL_INLINE)
-#define __BIONIC_GET_DEVICE_API_LEVEL_INLINE static inline /* for versioner */
-#endif
+#include <sys/cdefs.h>
__BEGIN_DECLS
@@ -48,3 +46,5 @@
}
__END_DECLS
+
+#endif // __BIONIC_GET_DEVICE_API_LEVEL_INLINE
diff --git a/libc/include/paths.h b/libc/include/paths.h
index b5b8610..0cf2789 100644
--- a/libc/include/paths.h
+++ b/libc/include/paths.h
@@ -47,7 +47,7 @@
#define _PATH_CONSOLE "/dev/console"
/** Default shell search path. */
-#define _PATH_DEFPATH "/sbin:/system/sbin:/apex/com.android.runtime/bin:/system/bin:/system/xbin:/odm/bin:/vendor/bin:/vendor/xbin"
+#define _PATH_DEFPATH "/sbin:/system/sbin:/product/bin:/apex/com.android.runtime/bin:/system/bin:/system/xbin:/odm/bin:/vendor/bin:/vendor/xbin"
/** Path to the directory containing device files. */
#define _PATH_DEV "/dev/"
diff --git a/libc/include/pthread.h b/libc/include/pthread.h
index 3089adc..724e5b7 100644
--- a/libc/include/pthread.h
+++ b/libc/include/pthread.h
@@ -137,7 +137,21 @@
const struct timespec* __timeout) __INTRODUCED_IN_64(28);
int pthread_cond_wait(pthread_cond_t* __cond, pthread_mutex_t* __mutex);
+#if defined(__clang__)
+/*
+ * Disable -Wbuiltin-requires-header because clang confuses this declaration with the one defined in
+ * "llvm/tools/clang/include/clang/Basic/Builtins.def", which did not define any formal arguments.
+ * It seems to be an upstream bug and the fix (https://reviews.llvm.org/D58531) is still under
+ * review. Thus, let's disable the warning for this function declaration.
+ */
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wbuiltin-requires-header"
+#endif
int pthread_create(pthread_t* __pthread_ptr, pthread_attr_t const* __attr, void* (*__start_routine)(void*), void*);
+#if defined(__clang__)
+#pragma clang diagnostic pop
+#endif
+
int pthread_detach(pthread_t __pthread);
void pthread_exit(void* __return_value) __noreturn;
diff --git a/libc/include/sys/param.h b/libc/include/sys/param.h
index 5cde4b7..79ae067 100644
--- a/libc/include/sys/param.h
+++ b/libc/include/sys/param.h
@@ -51,8 +51,19 @@
#endif
#define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
-/** Returns true if the argument is a power of two. */
-#define powerof2(x) ((((x)-1)&(x))==0)
+/**
+ * Returns true if the binary representation of the argument is all zeros
+ * or has exactly one bit set. Contrary to the macro name, this macro
+ * DOES NOT determine if the provided value is a power of 2. In particular,
+ * this function falsely returns true for powerof2(0) and some negative
+ * numbers.
+ */
+#define powerof2(x) \
+ ({ \
+ __typeof__(x) _x = (x); \
+ __typeof__(x) _x2; \
+ __builtin_add_overflow(_x, -1, &_x2) ? 1 : ((_x2 & _x) == 0); \
+ })
/** Returns the lesser of its two arguments. */
#define MIN(a,b) (((a)<(b))?(a):(b))
diff --git a/libc/kernel/uapi/linux/android/binder.h b/libc/kernel/uapi/linux/android/binder.h
index 2d00a79..542cf1c 100644
--- a/libc/kernel/uapi/linux/android/binder.h
+++ b/libc/kernel/uapi/linux/android/binder.h
@@ -34,6 +34,7 @@
enum {
FLAT_BINDER_FLAG_PRIORITY_MASK = 0xff,
FLAT_BINDER_FLAG_ACCEPTS_FDS = 0x100,
+ FLAT_BINDER_FLAG_TXN_SECURITY_CTX = 0x1000,
};
#ifdef BINDER_IPC_32BIT
typedef __u32 binder_size_t;
@@ -120,6 +121,7 @@
#define BINDER_VERSION _IOWR('b', 9, struct binder_version)
#define BINDER_GET_NODE_DEBUG_INFO _IOWR('b', 11, struct binder_node_debug_info)
#define BINDER_GET_NODE_INFO_FOR_REF _IOWR('b', 12, struct binder_node_info_for_ref)
+#define BINDER_SET_CONTEXT_MGR_EXT _IOW('b', 13, struct flat_binder_object)
enum transaction_flags {
TF_ONE_WAY = 0x01,
TF_ROOT_OBJECT = 0x04,
@@ -146,6 +148,10 @@
__u8 buf[8];
} data;
};
+struct binder_transaction_data_secctx {
+ struct binder_transaction_data transaction_data;
+ binder_uintptr_t secctx;
+};
struct binder_transaction_data_sg {
struct binder_transaction_data transaction_data;
binder_size_t buffers_size;
@@ -170,6 +176,7 @@
enum binder_driver_return_protocol {
BR_ERROR = _IOR('r', 0, __s32),
BR_OK = _IO('r', 1),
+ BR_TRANSACTION_SEC_CTX = _IOR('r', 2, struct binder_transaction_data_secctx),
BR_TRANSACTION = _IOR('r', 2, struct binder_transaction_data),
BR_REPLY = _IOR('r', 3, struct binder_transaction_data),
BR_ACQUIRE_RESULT = _IOR('r', 4, __s32),
diff --git a/libc/kernel/uapi/linux/version.h b/libc/kernel/uapi/linux/version.h
index 6ec3412..43c04d1 100644
--- a/libc/kernel/uapi/linux/version.h
+++ b/libc/kernel/uapi/linux/version.h
@@ -16,5 +16,5 @@
***
****************************************************************************
****************************************************************************/
-#define LINUX_VERSION_CODE 327680
+#define LINUX_VERSION_CODE 327683
#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
diff --git a/libc/private/__bionic_get_shell_path.h b/libc/private/__bionic_get_shell_path.h
new file mode 100644
index 0000000..171c14a
--- /dev/null
+++ b/libc/private/__bionic_get_shell_path.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ * 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.
+ *
+ * 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.
+ */
+
+#pragma once
+
+extern "C" const char* __bionic_get_shell_path();
diff --git a/libc/stdio/stdio.cpp b/libc/stdio/stdio.cpp
index d7b69dc..4cec757 100644
--- a/libc/stdio/stdio.cpp
+++ b/libc/stdio/stdio.cpp
@@ -52,6 +52,7 @@
#include "local.h"
#include "glue.h"
+#include "private/__bionic_get_shell_path.h"
#include "private/bionic_fortify.h"
#include "private/ErrnoRestorer.h"
#include "private/thread_private.h"
@@ -290,7 +291,7 @@
if (fcntl(fd, F_SETFL, fd_flags | O_APPEND) == -1) return nullptr;
}
- // Make sure O_CLOEXEC is set on the underlying fd if our mode has 'x'.
+ // Make sure O_CLOEXEC is set on the underlying fd if our mode has 'e'.
if ((mode_flags & O_CLOEXEC) && !((tmp = fcntl(fd, F_GETFD)) & FD_CLOEXEC)) {
fcntl(fd, F_SETFD, tmp | FD_CLOEXEC);
}
@@ -1169,11 +1170,6 @@
return (__sfvwrite(fp, &uio) == 0) ? count : ((n - uio.uio_resid) / size);
}
-static int __close_if_popened(FILE* fp) {
- if (_EXT(fp)->_popen_pid > 0) close(fileno(fp));
- return 0;
-}
-
static FILE* __popen_fail(int fds[2]) {
ErrnoRestorer errno_restorer;
close(fds[0]);
@@ -1219,14 +1215,11 @@
if (pid == 0) {
close(fds[parent]);
- // POSIX says "The popen() function shall ensure that any streams from previous popen() calls
- // that remain open in the parent process are closed in the new child process."
- _fwalk(__close_if_popened);
// dup2 so that the child fd isn't closed on exec.
if (dup2(fds[child], desired_child_fd) == -1) _exit(127);
close(fds[child]);
if (bidirectional) dup2(STDOUT_FILENO, STDIN_FILENO);
- execl(_PATH_BSHELL, "sh", "-c", cmd, nullptr);
+ execl(__bionic_get_shell_path(), "sh", "-c", cmd, nullptr);
_exit(127);
}
diff --git a/libc/tzcode/bionic.cpp b/libc/tzcode/bionic.cpp
index 9051308..1742d79 100644
--- a/libc/tzcode/bionic.cpp
+++ b/libc/tzcode/bionic.cpp
@@ -228,13 +228,18 @@
if (fd >= 0) return fd;
#else
// On the host, we don't expect those locations to exist, and we're not
- // worried about security so we trust $ANDROID_DATA, $ANDROID_RUNTIME_ROOT
- // and $ANDROID_ROOT to point us in the right direction.
+ // worried about security so we trust $ANDROID_DATA, $ANDROID_RUNTIME_ROOT,
+ // $ANDROID_TZDATA_ROOT, and $ANDROID_ROOT to point us in the right direction.
char* path = make_path("ANDROID_DATA", "/misc/zoneinfo/current/tzdata");
fd = __bionic_open_tzdata_path(path, olson_id, entry_length);
free(path);
if (fd >= 0) return fd;
+ path = make_path("ANDROID_TZDATA_ROOT", "/etc/tz/tzdata");
+ fd = __bionic_open_tzdata_path(path, olson_id, entry_length);
+ free(path);
+ if (fd >= 0) return fd;
+
path = make_path("ANDROID_RUNTIME_ROOT", "/etc/tz/tzdata");
fd = __bionic_open_tzdata_path(path, olson_id, entry_length);
free(path);
diff --git a/libc/tzcode/strptime.c b/libc/tzcode/strptime.c
index 0e9a7d3..41eaa9b 100644
--- a/libc/tzcode/strptime.c
+++ b/libc/tzcode/strptime.c
@@ -172,6 +172,12 @@
return (NULL);
break;
+ case 'F': /* The date as "%Y-%m-%d". */
+ _LEGAL_ALT(0);
+ if (!(bp = _strptime(bp, "%Y-%m-%d", tm, cr)))
+ return (NULL);
+ continue;
+
case 'R': /* The time as "%H:%M". */
_LEGAL_ALT(0);
if (!(bp = _strptime(bp, "%H:%M", tm, cr)))
@@ -190,6 +196,12 @@
return (NULL);
break;
+ case 'v': /* The date as "%e-%b-%Y". */
+ _LEGAL_ALT(0);
+ if (!(bp = _strptime(bp, "%e-%b-%Y", tm, cr)))
+ return (NULL);
+ break;
+
case 'X': /* The time, using the locale's format. */
_LEGAL_ALT(_ALT_E);
if (!(bp = _strptime(bp, _ctloc(t_fmt), tm, cr)))
@@ -305,6 +317,7 @@
tm->tm_mon--;
break;
+ case 'P':
case 'p': /* The locale's equivalent of AM/PM. */
_LEGAL_ALT(0);
/* AM? */
@@ -377,6 +390,33 @@
return (NULL);
break;
+ case 'u': /* The day of week, monday = 1. */
+ _LEGAL_ALT(_ALT_O);
+ if (!(_conv_num(&bp, &i, 1, 7)))
+ return (NULL);
+ tm->tm_wday = i % 7;
+ continue;
+
+ case 'g': /* The year corresponding to the ISO week
+ * number but without the century.
+ */
+ if (!(_conv_num(&bp, &i, 0, 99)))
+ return (NULL);
+ continue;
+
+ case 'G': /* The year corresponding to the ISO week
+ * number with century.
+ */
+ do
+ bp++;
+ while (isdigit(*bp));
+ continue;
+
+ case 'V': /* The ISO 8601:1988 week number as decimal */
+ if (!(_conv_num(&bp, &i, 0, 53)))
+ return (NULL);
+ continue;
+
case 'Y': /* The year. */
_LEGAL_ALT(_ALT_E);
if (!(_conv_num(&bp, &i, 0, 9999)))
diff --git a/linker/ld.config.format.md b/linker/ld.config.format.md
index 686d6be..faf5cc8 100644
--- a/linker/ld.config.format.md
+++ b/linker/ld.config.format.md
@@ -79,5 +79,8 @@
# and links it to default namespace
namespace.ns.links = default
namespace.ns.link.default.shared_libs = libc.so:libdl.so:libm.so:libstdc++.so
+
+# This defines what libraries are allowed to be loaded from ns1
+namespace.ns1.whitelisted = libsomething.so
```
diff --git a/linker/linker.cpp b/linker/linker.cpp
index 49c8f11..c60ab6a 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -4156,6 +4156,7 @@
ns->set_isolated(ns_config->isolated());
ns->set_default_library_paths(ns_config->search_paths());
ns->set_permitted_paths(ns_config->permitted_paths());
+ ns->set_whitelisted_libs(ns_config->whitelisted_libs());
namespaces[ns_config->name()] = ns;
if (ns_config->visible()) {
diff --git a/linker/linker_config.cpp b/linker/linker_config.cpp
index f7f9c41..7741904 100644
--- a/linker/linker_config.cpp
+++ b/linker/linker_config.cpp
@@ -60,7 +60,7 @@
};
explicit ConfigParser(std::string&& content)
- : content_(content), p_(0), lineno_(0), was_end_of_file_(false) {}
+ : content_(std::move(content)), p_(0), lineno_(0), was_end_of_file_(false) {}
/*
* Possible return values
@@ -147,7 +147,7 @@
PropertyValue() = default;
PropertyValue(std::string&& value, size_t lineno)
- : value_(value), lineno_(lineno) {}
+ : value_(std::move(value)), lineno_(lineno) {}
const std::string& value() const {
return value_;
@@ -362,7 +362,7 @@
class Properties {
public:
explicit Properties(std::unordered_map<std::string, PropertyValue>&& properties)
- : properties_(properties), target_sdk_version_(__ANDROID_API__) {}
+ : properties_(std::move(properties)), target_sdk_version_(__ANDROID_API__) {}
std::vector<std::string> get_strings(const std::string& name, size_t* lineno = nullptr) const {
auto it = find_property(name, lineno);
@@ -411,7 +411,7 @@
static std::string vndk = Config::get_vndk_version_string('-');
params.push_back({ "VNDK_VER", vndk });
- for (auto&& path : paths) {
+ for (auto& path : paths) {
format_string(&path, params);
}
@@ -552,6 +552,12 @@
ns_config->set_isolated(properties.get_bool(property_name_prefix + ".isolated"));
ns_config->set_visible(properties.get_bool(property_name_prefix + ".visible"));
+ std::string whitelisted =
+ properties.get_string(property_name_prefix + ".whitelisted", &lineno);
+ if (!whitelisted.empty()) {
+ ns_config->set_whitelisted_libs(android::base::Split(whitelisted, ":"));
+ }
+
// these are affected by is_asan flag
if (is_asan) {
property_name_prefix += ".asan";
diff --git a/linker/linker_config.h b/linker/linker_config.h
index 49739ee..75d9378 100644
--- a/linker/linker_config.h
+++ b/linker/linker_config.h
@@ -92,6 +92,10 @@
return permitted_paths_;
}
+ const std::vector<std::string>& whitelisted_libs() const {
+ return whitelisted_libs_;
+ }
+
const std::vector<NamespaceLinkConfig>& links() const {
return namespace_links_;
}
@@ -110,11 +114,15 @@
}
void set_search_paths(std::vector<std::string>&& search_paths) {
- search_paths_ = search_paths;
+ search_paths_ = std::move(search_paths);
}
void set_permitted_paths(std::vector<std::string>&& permitted_paths) {
- permitted_paths_ = permitted_paths;
+ permitted_paths_ = std::move(permitted_paths);
+ }
+
+ void set_whitelisted_libs(std::vector<std::string>&& whitelisted_libs) {
+ whitelisted_libs_ = std::move(whitelisted_libs);
}
private:
const std::string name_;
@@ -122,6 +130,7 @@
bool visible_;
std::vector<std::string> search_paths_;
std::vector<std::string> permitted_paths_;
+ std::vector<std::string> whitelisted_libs_;
std::vector<NamespaceLinkConfig> namespace_links_;
DISALLOW_IMPLICIT_CONSTRUCTORS(NamespaceConfig);
diff --git a/linker/linker_config_test.cpp b/linker/linker_config_test.cpp
index 6a55bb2..4937056 100644
--- a/linker/linker_config_test.cpp
+++ b/linker/linker_config_test.cpp
@@ -56,6 +56,7 @@
"enable.target.sdk.version = true\n"
"additional.namespaces=system\n"
"additional.namespaces+=vndk\n"
+ "additional.namespaces+=vndk_in_system\n"
"namespace.default.isolated = true\n"
"namespace.default.search.paths = /vendor/${LIB}\n"
"namespace.default.permitted.paths = /vendor/${LIB}\n"
@@ -82,6 +83,12 @@
"namespace.vndk.asan.search.paths += /system/${LIB}/vndk\n"
"namespace.vndk.links = default\n"
"namespace.vndk.link.default.allow_all_shared_libs = true\n"
+ "namespace.vndk.link.vndk_in_system.allow_all_shared_libs = true\n"
+ "namespace.vndk_in_system.isolated = true\n"
+ "namespace.vndk_in_system.visible = true\n"
+ "namespace.vndk_in_system.search.paths = /system/${LIB}\n"
+ "namespace.vndk_in_system.permitted.paths = /system/${LIB}\n"
+ "namespace.vndk_in_system.whitelisted = libz.so:libyuv.so:libtinyxml2.so\n"
"\n";
static bool write_version(const std::string& path, uint32_t version) {
@@ -165,20 +172,24 @@
ASSERT_FALSE(default_ns_links[1].allow_all_shared_libs());
auto& ns_configs = config->namespace_configs();
- ASSERT_EQ(3U, ns_configs.size());
+ ASSERT_EQ(4U, ns_configs.size());
// find second namespace
const NamespaceConfig* ns_system = nullptr;
const NamespaceConfig* ns_vndk = nullptr;
+ const NamespaceConfig* ns_vndk_in_system = nullptr;
for (auto& ns : ns_configs) {
std::string ns_name = ns->name();
- ASSERT_TRUE(ns_name == "system" || ns_name == "default" || ns_name == "vndk")
+ ASSERT_TRUE(ns_name == "system" || ns_name == "default" ||
+ ns_name == "vndk" || ns_name == "vndk_in_system")
<< "unexpected ns name: " << ns->name();
if (ns_name == "system") {
ns_system = ns.get();
} else if (ns_name == "vndk") {
ns_vndk = ns.get();
+ } else if (ns_name == "vndk_in_system") {
+ ns_vndk_in_system = ns.get();
}
}
@@ -199,6 +210,11 @@
ASSERT_EQ(1U, ns_vndk_links.size());
ASSERT_EQ("default", ns_vndk_links[0].ns_name());
ASSERT_TRUE(ns_vndk_links[0].allow_all_shared_libs());
+
+ ASSERT_TRUE(ns_vndk_in_system != nullptr) << "vndk_in_system namespace was not found";
+ ASSERT_EQ(
+ std::vector<std::string>({"libz.so", "libyuv.so", "libtinyxml2.so"}),
+ ns_vndk_in_system->whitelisted_libs());
}
TEST(linker_config, smoke) {
diff --git a/linker/linker_namespaces.cpp b/linker/linker_namespaces.cpp
index fd72cdc..e870ef7 100644
--- a/linker/linker_namespaces.cpp
+++ b/linker/linker_namespaces.cpp
@@ -38,6 +38,14 @@
return true;
}
+ if (!whitelisted_libs_.empty()) {
+ const char *lib_name = basename(file.c_str());
+ if (std::find(whitelisted_libs_.begin(), whitelisted_libs_.end(),
+ lib_name) == whitelisted_libs_.end()) {
+ return false;
+ }
+ }
+
for (const auto& dir : ld_library_paths_) {
if (file_is_in_dir(file, dir)) {
return true;
diff --git a/linker/linker_namespaces.h b/linker/linker_namespaces.h
index cd8b09d..f4428eb 100644
--- a/linker/linker_namespaces.h
+++ b/linker/linker_namespaces.h
@@ -87,14 +87,14 @@
return ld_library_paths_;
}
void set_ld_library_paths(std::vector<std::string>&& library_paths) {
- ld_library_paths_ = library_paths;
+ ld_library_paths_ = std::move(library_paths);
}
const std::vector<std::string>& get_default_library_paths() const {
return default_library_paths_;
}
void set_default_library_paths(std::vector<std::string>&& library_paths) {
- default_library_paths_ = library_paths;
+ default_library_paths_ = std::move(library_paths);
}
void set_default_library_paths(const std::vector<std::string>& library_paths) {
default_library_paths_ = library_paths;
@@ -104,12 +104,22 @@
return permitted_paths_;
}
void set_permitted_paths(std::vector<std::string>&& permitted_paths) {
- permitted_paths_ = permitted_paths;
+ permitted_paths_ = std::move(permitted_paths);
}
void set_permitted_paths(const std::vector<std::string>& permitted_paths) {
permitted_paths_ = permitted_paths;
}
+ const std::vector<std::string>& get_whitelisted_libs() const {
+ return whitelisted_libs_;
+ }
+ void set_whitelisted_libs(std::vector<std::string>&& whitelisted_libs) {
+ whitelisted_libs_ = std::move(whitelisted_libs);
+ }
+ void set_whitelisted_libs(const std::vector<std::string>& whitelisted_libs) {
+ whitelisted_libs_ = whitelisted_libs;
+ }
+
const std::vector<android_namespace_link_t>& linked_namespaces() const {
return linked_namespaces_;
}
@@ -157,6 +167,7 @@
std::vector<std::string> ld_library_paths_;
std::vector<std::string> default_library_paths_;
std::vector<std::string> permitted_paths_;
+ std::vector<std::string> whitelisted_libs_;
// Loader looks into linked namespace if it was not able
// to find a library in this namespace. Note that library
// lookup in linked namespaces are limited by the list of
diff --git a/tests/Android.bp b/tests/Android.bp
index 894a7cb..fe97fee 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -159,6 +159,7 @@
"sys_epoll_test.cpp",
"sys_mman_test.cpp",
"sys_msg_test.cpp",
+ "sys_param_test.cpp",
"sys_personality_test.cpp",
"sys_prctl_test.cpp",
"sys_procfs_test.cpp",
diff --git a/tests/__aeabi_read_tp_test.cpp b/tests/__aeabi_read_tp_test.cpp
index 6974658..7209a75 100644
--- a/tests/__aeabi_read_tp_test.cpp
+++ b/tests/__aeabi_read_tp_test.cpp
@@ -38,6 +38,6 @@
#if defined(__arm__)
ASSERT_EQ(__aeabi_read_tp(), static_cast<void*>(__get_tls()));
#else
- GTEST_LOG_(INFO) << "__aeabi_read_tp is only available on arm32.\n";
+ GTEST_SKIP() << "__aeabi_read_tp is only available on arm32";
#endif
}
diff --git a/tests/async_safe_test.cpp b/tests/async_safe_test.cpp
index 4940e3a..6c4758e 100644
--- a/tests/async_safe_test.cpp
+++ b/tests/async_safe_test.cpp
@@ -104,7 +104,7 @@
async_safe_format_buffer(buf, sizeof(buf), "a%lld,%d,%d,%dz", 0x1000000000LL, 6, 7, 8);
EXPECT_STREQ("a68719476736,6,7,8z", buf);
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif // __BIONIC__
}
@@ -114,7 +114,7 @@
async_safe_format_buffer(buf, sizeof(buf), "%d", INT_MAX);
EXPECT_STREQ("2147483647", buf);
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif // __BIONIC__
}
@@ -124,7 +124,7 @@
async_safe_format_buffer(buf, sizeof(buf), "%d", INT_MIN);
EXPECT_STREQ("-2147483648", buf);
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif // __BIONIC__
}
@@ -138,7 +138,7 @@
EXPECT_STREQ("2147483647", buf);
#endif
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif // __BIONIC__
}
@@ -152,7 +152,7 @@
EXPECT_STREQ("-2147483648", buf);
#endif
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif // __BIONIC__
}
@@ -162,7 +162,7 @@
async_safe_format_buffer(buf, sizeof(buf), "%lld", LLONG_MAX);
EXPECT_STREQ("9223372036854775807", buf);
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif // __BIONIC__
}
@@ -172,7 +172,7 @@
async_safe_format_buffer(buf, sizeof(buf), "%lld", LLONG_MIN);
EXPECT_STREQ("-9223372036854775808", buf);
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif // __BIONIC__
}
@@ -196,6 +196,6 @@
ASSERT_EQ(4, async_safe_format_buffer(buf, 2, "xxxx"));
EXPECT_STREQ("x", buf);
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif // __BIONIC__
}
diff --git a/tests/dl_test.cpp b/tests/dl_test.cpp
index 468ce3d..9e46394 100644
--- a/tests/dl_test.cpp
+++ b/tests/dl_test.cpp
@@ -138,7 +138,7 @@
TEST(dl, preinit_system_calls) {
#if defined(__BIONIC__)
- SKIP_WITH_HWASAN; // hwasan not initialized in preinit_array, b/124007027
+ SKIP_WITH_HWASAN << "hwasan not initialized in preinit_array, b/124007027";
std::string helper = GetTestlibRoot() +
"/preinit_syscall_test_helper/preinit_syscall_test_helper";
chmod(helper.c_str(), 0755); // TODO: "x" lost in CTS, b/34945607
@@ -150,7 +150,7 @@
TEST(dl, preinit_getauxval) {
#if defined(__BIONIC__)
- SKIP_WITH_HWASAN; // hwasan not initialized in preinit_array, b/124007027
+ SKIP_WITH_HWASAN << "hwasan not initialized in preinit_array, b/124007027";
std::string helper = GetTestlibRoot() +
"/preinit_getauxval_test_helper/preinit_getauxval_test_helper";
chmod(helper.c_str(), 0755); // TODO: "x" lost in CTS, b/34945607
@@ -242,7 +242,7 @@
// whose search paths include the 'ns2/' subdir.
TEST(dl, exec_with_ld_config_file) {
#if defined(__BIONIC__)
- SKIP_WITH_HWASAN; // libclang_rt.hwasan is not found with custom ld config
+ SKIP_WITH_HWASAN << "libclang_rt.hwasan is not found with custom ld config";
if (!is_debuggable_build()) {
// LD_CONFIG_FILE is not supported on user build
return;
@@ -265,7 +265,7 @@
// additional namespaces other than the default namespace.
TEST(dl, exec_with_ld_config_file_with_ld_preload) {
#if defined(__BIONIC__)
- SKIP_WITH_HWASAN; // libclang_rt.hwasan is not found with custom ld config
+ SKIP_WITH_HWASAN << "libclang_rt.hwasan is not found with custom ld config";
if (!is_debuggable_build()) {
// LD_CONFIG_FILE is not supported on user build
return;
diff --git a/tests/dlext_test.cpp b/tests/dlext_test.cpp
index f5e0c9c..7949d0f 100644
--- a/tests/dlext_test.cpp
+++ b/tests/dlext_test.cpp
@@ -540,10 +540,7 @@
}
TEST_F(DlExtRelroSharingTest, VerifyMemorySaving) {
- if (geteuid() != 0) {
- GTEST_LOG_(INFO) << "This test must be run as root.\n";
- return;
- }
+ if (geteuid() != 0) GTEST_SKIP() << "This test must be run as root";
TemporaryFile tf; // Use tf to get an unique filename.
ASSERT_NOERROR(close(tf.fd));
diff --git a/tests/dlfcn_test.cpp b/tests/dlfcn_test.cpp
index ff5b1a9..f3be988 100644
--- a/tests/dlfcn_test.cpp
+++ b/tests/dlfcn_test.cpp
@@ -260,8 +260,7 @@
TEST(dlfcn, dlopen_vdso) {
#if __has_include(<sys/auxv.h>)
if (getauxval(AT_SYSINFO_EHDR) == 0) {
- GTEST_LOG_(INFO) << "getauxval(AT_SYSINFO_EHDR) == 0, skipping this test.";
- return;
+ GTEST_SKIP() << "getauxval(AT_SYSINFO_EHDR) == 0, skipping this test";
}
#endif
@@ -976,9 +975,9 @@
#if defined(__BIONIC__)
ASSERT_EQ(handle1, handle2);
#else
- GTEST_LOG_(INFO) << "Skipping ASSERT_EQ(handle1, handle2) for glibc: "
- "it loads a separate copy of the main executable "
- "on dlopen by absolute path.";
+ GTEST_SKIP() << "Skipping ASSERT_EQ(handle1, handle2) for glibc: "
+ "it loads a separate copy of the main executable "
+ "on dlopen by absolute path";
#endif
}
@@ -1003,7 +1002,10 @@
#define ALTERNATE_PATH_TO_LIBC ALTERNATE_PATH_TO_SYSTEM_LIB "libc.so"
TEST(dlfcn, dladdr_libc) {
-#if defined(__BIONIC__)
+#if defined(__GLIBC__)
+ GTEST_SKIP() << "glibc returns libc.so's ldconfig path, which is a symlink (not a realpath)";
+#endif
+
Dl_info info;
void* addr = reinterpret_cast<void*>(puts); // well-known libc function
ASSERT_TRUE(dladdr(addr, &info) != 0);
@@ -1025,10 +1027,6 @@
// TODO: add check for dfi_fbase
ASSERT_STREQ("puts", info.dli_sname);
ASSERT_EQ(addr, info.dli_saddr);
-#else
- GTEST_LOG_(INFO) << "This test does nothing for glibc. Glibc returns path from ldconfig "
- "for libc.so, which is symlink itself (not a realpath).\n";
-#endif
}
TEST(dlfcn, dladdr_invalid) {
@@ -1066,7 +1064,7 @@
ASSERT_STREQ("getRandomNumber", dlinfo.dli_sname);
ASSERT_SUBSTR("libgnu-hash-table-library.so", dlinfo.dli_fname);
#else
- GTEST_LOG_(INFO) << "This test does nothing for mips/mips64; mips toolchain does not support '--hash-style=gnu'\n";
+ GTEST_SKIP() << "mips toolchain does not support '--hash-style=gnu'";
#endif
}
@@ -1184,13 +1182,13 @@
// that calls dlopen(libc...). This is to test the situation
// described in b/7941716.
TEST(dlfcn, dlopen_dlopen_from_ctor) {
-#if defined(__BIONIC__)
+#if defined(__GLIBC__)
+ GTEST_SKIP() << "glibc segfaults if you try to call dlopen from a constructor";
+#endif
+
void* handle = dlopen("libtest_dlopen_from_ctor_main.so", RTLD_NOW);
ASSERT_TRUE(handle != nullptr) << dlerror();
dlclose(handle);
-#else
- GTEST_LOG_(INFO) << "This test is disabled for glibc (glibc segfaults if you try to call dlopen from a constructor).\n";
-#endif
}
static std::string g_fini_call_order_str;
diff --git a/tests/elftls_dl_test.cpp b/tests/elftls_dl_test.cpp
index 36bdc3b..88225d8 100644
--- a/tests/elftls_dl_test.cpp
+++ b/tests/elftls_dl_test.cpp
@@ -146,7 +146,7 @@
ASSERT_EQ(nullptr, missing_weak_dyn_tls_addr());
}).join();
#else
- GTEST_LOG_(INFO) << "This test is only run on TLSDESC-based targets.\n";
+ GTEST_SKIP() << "This test is only run on TLSDESC-based targets";
#endif
}
@@ -215,7 +215,7 @@
#undef LOAD_LIB
#else
- GTEST_LOG_(INFO) << "This test is skipped for glibc because it tests Bionic internals.";
+ GTEST_SKIP() << "test doesn't apply to glibc";
#endif
}
@@ -266,6 +266,6 @@
dlclose(lib);
}
#else
- GTEST_LOG_(INFO) << "This test is skipped for glibc because it tests Bionic internals.";
+ GTEST_SKIP() << "test doesn't apply to glibc";
#endif
}
diff --git a/tests/endian_test.cpp b/tests/endian_test.cpp
index 85d56f0..3d6dc4d 100644
--- a/tests/endian_test.cpp
+++ b/tests/endian_test.cpp
@@ -46,7 +46,7 @@
ASSERT_EQ(be32, htonl(le32));
ASSERT_EQ(be64, htonq(le64));
#else
- GTEST_LOG_(INFO) << "glibc doesn't have these macros";
+ GTEST_SKIP() << "glibc doesn't have htons/htonl/htonq in <endian.h>";
#endif
}
@@ -56,7 +56,7 @@
ASSERT_EQ(le32, ntohl(be32));
ASSERT_EQ(le64, ntohq(be64));
#else
- GTEST_LOG_(INFO) << "glibc doesn't have these macros";
+ GTEST_SKIP() << "glibc doesn't have ntohs/ntohl/ntohq in <endian.h>";
#endif
}
@@ -90,7 +90,7 @@
ASSERT_EQ(le32, betoh32(be32));
ASSERT_EQ(le64, betoh64(be64));
#else
- GTEST_LOG_(INFO) << "glibc doesn't have these macros";
+ GTEST_SKIP() << "glibc doesn't have betoh16/betoh32/betoh64";
#endif
}
@@ -100,6 +100,6 @@
ASSERT_EQ(le32, letoh32(le32));
ASSERT_EQ(le64, letoh64(le64));
#else
- GTEST_LOG_(INFO) << "glibc doesn't have these macros";
+ GTEST_SKIP() << "glibc doesn't have letoh16/letoh32/letoh64";
#endif
}
diff --git a/tests/fortify_test.cpp b/tests/fortify_test.cpp
index bc33251..489b701 100644
--- a/tests/fortify_test.cpp
+++ b/tests/fortify_test.cpp
@@ -143,7 +143,7 @@
ASSERT_FORTIFY(stpcpy(myfoo.empty, src));
free(src);
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "stpcpy not available";
#endif // __BIONIC__
}
@@ -155,7 +155,7 @@
ASSERT_FORTIFY(strcpy(myfoo.empty, src));
free(src);
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "glibc is broken";
#endif // __BIONIC__
}
@@ -167,7 +167,7 @@
ASSERT_FORTIFY(strcpy(myfoo.empty, src));
free(src);
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "glibc is broken";
#endif // __BIONIC__
}
@@ -179,7 +179,7 @@
ASSERT_FORTIFY(strcpy(myfoo.one, src));
free(src);
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "glibc is broken";
#endif // __BIONIC__
}
@@ -191,7 +191,7 @@
ASSERT_FORTIFY(printf("%s", strchr(myfoo.a, 'a')));
ASSERT_FORTIFY(printf("%s", strchr(static_cast<const char*>(myfoo.a), 'a')));
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "glibc is broken";
#endif // __BIONIC__
}
@@ -203,7 +203,7 @@
ASSERT_FORTIFY(printf("%s", strrchr(myfoo.a, 'a')));
ASSERT_FORTIFY(printf("%s", strrchr(static_cast<const char*>(myfoo.a), 'a')));
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "glibc is broken";
#endif // __BIONIC__
}
@@ -215,7 +215,7 @@
ASSERT_FORTIFY(printf("%s", memchr(myfoo.a, 'a', asize)));
ASSERT_FORTIFY(printf("%s", memchr(static_cast<const void*>(myfoo.a), 'a', asize)));
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "glibc is broken";
#endif // __BIONIC__
}
@@ -227,7 +227,7 @@
ASSERT_FORTIFY(printf("%s", memrchr(myfoo.a, 'a', asize)));
ASSERT_FORTIFY(printf("%s", memrchr(static_cast<const void*>(myfoo.a), 'a', asize)));
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "glibc is broken";
#endif // __BIONIC__
}
@@ -238,7 +238,7 @@
size_t n = strlen(myfoo.a);
ASSERT_FORTIFY(strlcpy(myfoo.one, myfoo.a, n));
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "strlcpy not available";
#endif // __BIONIC__
}
@@ -250,7 +250,7 @@
size_t n = strlen(myfoo.a);
ASSERT_FORTIFY(strlcat(myfoo.one, myfoo.a, n));
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "strlcat not available";
#endif // __BIONIC__
}
@@ -315,7 +315,7 @@
ASSERT_FORTIFY(strcpy(buf, orig));
free(orig);
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "glibc is broken";
#endif // __BIONIC__
}
@@ -327,7 +327,7 @@
ASSERT_FORTIFY(strcpy(buf, orig));
free(orig);
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "glibc is broken";
#endif // __BIONIC__
}
@@ -339,7 +339,7 @@
ASSERT_FORTIFY(strcpy(buf, orig));
free(orig);
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "glibc is broken";
#endif // __BIONIC__
}
@@ -351,7 +351,7 @@
ASSERT_FORTIFY(strcpy(buf, orig));
free(orig);
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "glibc is broken";
#endif // __BIONIC__
}
@@ -361,7 +361,7 @@
memcpy(buf, "0123456789", sizeof(buf));
ASSERT_FORTIFY(printf("%zd", strlen(buf)));
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "glibc is broken";
#endif // __BIONIC__
}
@@ -371,7 +371,7 @@
memcpy(buf, "0123456789", sizeof(buf));
ASSERT_FORTIFY(printf("%s", strchr(buf, 'a')));
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "glibc is broken";
#endif // __BIONIC__
}
@@ -381,7 +381,7 @@
memcpy(buf, "0123456789", sizeof(buf));
ASSERT_FORTIFY(printf("%s", strrchr(buf, 'a')));
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "glibc is broken";
#endif // __BIONIC__
}
@@ -393,7 +393,7 @@
size_t n = strlen(bufa);
ASSERT_FORTIFY(strlcpy(bufb, bufa, n));
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "strlcpy not available";
#endif // __BIONIC__
}
@@ -406,7 +406,7 @@
size_t n = strlen(bufa);
ASSERT_FORTIFY(strlcat(bufb, bufa, n));
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "strlcat not available";
#endif // __BIONIC__
}
diff --git a/tests/getauxval_test.cpp b/tests/getauxval_test.cpp
index aa21817..f4ec7f5 100644
--- a/tests/getauxval_test.cpp
+++ b/tests/getauxval_test.cpp
@@ -61,5 +61,5 @@
return;
}
#endif
- GTEST_LOG_(INFO) << "This test is only meaningful for 32-bit ARM code on 64-bit devices.\n";
+ GTEST_SKIP() << "This test is only meaningful for 32-bit ARM code on 64-bit devices";
}
diff --git a/tests/getcwd_test.cpp b/tests/getcwd_test.cpp
index 791ffae..97b1d4f 100644
--- a/tests/getcwd_test.cpp
+++ b/tests/getcwd_test.cpp
@@ -51,7 +51,7 @@
}
TEST(getcwd, auto_too_large) {
- SKIP_WITH_HWASAN; // allocation size too large
+ SKIP_WITH_HWASAN << "allocation size too large";
// If we ask the library to allocate an unreasonably large buffer, ERANGE.
errno = 0;
char* cwd = getcwd(nullptr, static_cast<size_t>(-1));
diff --git a/tests/grp_pwd_file_test.cpp b/tests/grp_pwd_file_test.cpp
index 66866fb..adcdbd6 100644
--- a/tests/grp_pwd_file_test.cpp
+++ b/tests/grp_pwd_file_test.cpp
@@ -103,7 +103,7 @@
EXPECT_FALSE(passwd_file.FindById(3, nullptr));
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif // __BIONIC__
}
@@ -123,7 +123,7 @@
EXPECT_FALSE(group_file.FindById(3, nullptr));
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif // __BIONIC__
}
@@ -161,7 +161,7 @@
EXPECT_FALSE(passwd_file.FindById(50, nullptr));
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif // __BIONIC__
}
@@ -197,7 +197,7 @@
EXPECT_FALSE(group_file.FindById(799, nullptr));
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif // __BIONIC__
}
@@ -219,7 +219,7 @@
FindAndCheckPasswdEntry(&passwd_file, "vendor_name", 3, 4, "dir", "shell");
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif // __BIONIC__
}
@@ -241,6 +241,6 @@
FindAndCheckGroupEntry(&group_file, "vendor_name", 2);
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif // __BIONIC__
}
diff --git a/tests/grp_pwd_test.cpp b/tests/grp_pwd_test.cpp
index eb8fe2a..b46839b 100644
--- a/tests/grp_pwd_test.cpp
+++ b/tests/grp_pwd_test.cpp
@@ -138,17 +138,13 @@
#else // !defined(__BIONIC__)
-static void print_no_getpwnam_test_info() {
- GTEST_LOG_(INFO) << "This test is about uid/username translation for Android, which does nothing on libc other than bionic.\n";
-}
-
static void check_get_passwd(const char* /* username */, uid_t /* uid */, uid_type_t /* uid_type */,
bool /* check_username */) {
- print_no_getpwnam_test_info();
+ GTEST_SKIP() << "bionic-only test";
}
static void check_get_passwd(const char* /* username */, uid_t /* uid */, uid_type_t /* uid_type */) {
- print_no_getpwnam_test_info();
+ GTEST_SKIP() << "bionic-only test";
}
#endif
@@ -311,7 +307,7 @@
expect_ids(uids);
#else
- print_no_getpwnam_test_info();
+ GTEST_SKIP() << "bionic-only test";
#endif
}
@@ -382,16 +378,12 @@
#else // !defined(__BIONIC__)
-static void print_no_getgrnam_test_info() {
- GTEST_LOG_(INFO) << "This test is about gid/group_name translation for Android, which does nothing on libc other than bionic.\n";
-}
-
static void check_get_group(const char*, gid_t, bool) {
- print_no_getgrnam_test_info();
+ GTEST_SKIP() << "bionic-only test";
}
static void check_get_group(const char*, gid_t) {
- print_no_getgrnam_test_info();
+ GTEST_SKIP() << "bionic-only test";
}
#endif
@@ -501,7 +493,7 @@
check_group(grp[0], "root", 0);
check_group(grp[1], "system", 1000);
#else
- print_no_getgrnam_test_info();
+ GTEST_SKIP() << "bionic-only test";
#endif
}
@@ -521,7 +513,7 @@
check_group(grp[0], "root", 0);
check_group(grp[1], "system", 1000);
#else
- print_no_getgrnam_test_info();
+ GTEST_SKIP() << "bionic-only test";
#endif
}
@@ -561,7 +553,7 @@
expect_ids(gids);
#else
- print_no_getgrnam_test_info();
+ GTEST_SKIP() << "bionic-only test";
#endif
}
@@ -590,7 +582,7 @@
TestAidNamePrefix("/vendor/etc/passwd");
#else
- print_no_getpwnam_test_info();
+ GTEST_SKIP() << "bionic-only test";
#endif
}
@@ -602,6 +594,6 @@
TestAidNamePrefix("/vendor/etc/group");
#else
- print_no_getgrnam_test_info();
+ GTEST_SKIP() << "bionic-only test";
#endif
}
diff --git a/tests/libgen_test.cpp b/tests/libgen_test.cpp
index d5b5eb6..24f7923 100644
--- a/tests/libgen_test.cpp
+++ b/tests/libgen_test.cpp
@@ -78,7 +78,7 @@
TestBasename(".", ".", 1, buf, sizeof(buf), 0);
TestBasename("..", "..", 2, buf, sizeof(buf), 0);
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "basename_r is only available on 32-bit bionic";
#endif // __BIONIC__
}
@@ -95,6 +95,6 @@
TestDirname(".", ".", 1, buf, sizeof(buf), 0);
TestDirname("..", ".", 1, buf, sizeof(buf), 0);
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "dirname_r is only available on 32-bit bionic";
#endif // __BIONIC__
}
diff --git a/tests/link_test.cpp b/tests/link_test.cpp
index 1bdee9f..cf5fc0b 100644
--- a/tests/link_test.cpp
+++ b/tests/link_test.cpp
@@ -231,6 +231,6 @@
}
ASSERT_TRUE(found);
#else
- GTEST_LOG_(INFO) << "dl_unwind_find_exidx is an ARM-only API\n";
+ GTEST_SKIP() << "dl_unwind_find_exidx is an ARM-only API";
#endif
}
diff --git a/tests/malloc_iterate_test.cpp b/tests/malloc_iterate_test.cpp
index 76583eb..9d4fe04 100644
--- a/tests/malloc_iterate_test.cpp
+++ b/tests/malloc_iterate_test.cpp
@@ -150,7 +150,7 @@
FreePtrs(&test_data);
#else
- GTEST_LOG_(INFO) << "Skipping, this is a bionic only test.";
+ GTEST_SKIP() << "bionic-only test";
#endif
}
@@ -169,7 +169,7 @@
FreePtrs(&test_data);
#else
- GTEST_LOG_(INFO) << "Skipping, this is a bionic only test.";
+ GTEST_SKIP() << "bionic-only test";
#endif
}
@@ -193,7 +193,7 @@
ASSERT_EQ(0UL, test_data.total_allocated_bytes);
#else
- GTEST_LOG_(INFO) << "Skipping, this is a bionic only test.";
+ GTEST_SKIP() << "bionic-only test";
#endif
}
@@ -222,6 +222,6 @@
ASSERT_NE(-1, wait_pid) << "Unknown failure in waitpid.";
ASSERT_EQ(0, wait_pid) << "malloc_disable did not prevent allocation calls.";
#else
- GTEST_LOG_(INFO) << "Skipping, this is a bionic only test.";
+ GTEST_SKIP() << "bionic-only test";
#endif
}
diff --git a/tests/malloc_test.cpp b/tests/malloc_test.cpp
index 9380680..706de15 100644
--- a/tests/malloc_test.cpp
+++ b/tests/malloc_test.cpp
@@ -94,7 +94,7 @@
}
TEST(malloc, memalign_multiple) {
- SKIP_WITH_HWASAN; // hwasan requires power of 2 alignment.
+ SKIP_WITH_HWASAN << "hwasan requires power of 2 alignment";
// Memalign test where the alignment is any value.
for (size_t i = 0; i <= 12; i++) {
for (size_t alignment = 1 << i; alignment < (1U << (i+1)); alignment++) {
@@ -341,6 +341,7 @@
TEST(malloc, malloc_info) {
#ifdef __BIONIC__
+ SKIP_WITH_HWASAN; // hwasan does not implement malloc_info
char* buf;
size_t bufsize;
FILE* memstream = open_memstream(&buf, &bufsize);
@@ -531,24 +532,24 @@
TEST(malloc, mallopt_decay) {
#if defined(__BIONIC__)
- SKIP_WITH_HWASAN; // hwasan does not implement mallopt
+ SKIP_WITH_HWASAN << "hwasan does not implement mallopt";
errno = 0;
ASSERT_EQ(1, mallopt(M_DECAY_TIME, 1));
ASSERT_EQ(1, mallopt(M_DECAY_TIME, 0));
ASSERT_EQ(1, mallopt(M_DECAY_TIME, 1));
ASSERT_EQ(1, mallopt(M_DECAY_TIME, 0));
#else
- GTEST_LOG_(INFO) << "This tests a bionic implementation detail.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif
}
TEST(malloc, mallopt_purge) {
#if defined(__BIONIC__)
- SKIP_WITH_HWASAN; // hwasan does not implement mallopt
+ SKIP_WITH_HWASAN << "hwasan does not implement mallopt";
errno = 0;
ASSERT_EQ(1, mallopt(M_PURGE, 0));
#else
- GTEST_LOG_(INFO) << "This tests a bionic implementation detail.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif
}
@@ -566,7 +567,7 @@
ASSERT_TRUE(reallocarray(nullptr, b, a) == nullptr);
ASSERT_EQ(ENOMEM, errno);
#else
- GTEST_LOG_(INFO) << "This test requires a C library with reallocarray.\n";
+ GTEST_SKIP() << "reallocarray not available";
#endif
}
@@ -576,13 +577,13 @@
ASSERT_TRUE(p != nullptr);
ASSERT_GE(malloc_usable_size(p), 64U);
#else
- GTEST_LOG_(INFO) << "This test requires a C library with reallocarray.\n";
+ GTEST_SKIP() << "reallocarray not available";
#endif
}
TEST(malloc, mallinfo) {
#if defined(__BIONIC__)
- SKIP_WITH_HWASAN; // hwasan does not implement mallinfo
+ SKIP_WITH_HWASAN << "hwasan does not implement mallinfo";
static size_t sizes[] = {
8, 32, 128, 4096, 32768, 131072, 1024000, 10240000, 20480000, 300000000
};
@@ -621,7 +622,7 @@
<< kMaxAllocs << " allocations.";
}
#else
- GTEST_LOG_(INFO) << "Host glibc does not pass this test, skipping.\n";
+ GTEST_SKIP() << "glibc is broken";
#endif
}
@@ -632,7 +633,7 @@
EXPECT_EQ(false, android_mallopt(unrecognized_option, nullptr, 0));
EXPECT_EQ(ENOTSUP, errno);
#else
- GTEST_LOG_(INFO) << "This tests a bionic implementation detail.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif
}
@@ -678,7 +679,7 @@
EXPECT_EQ(ENOTSUP, errno);
}
#else
- GTEST_LOG_(INFO) << "This tests a bionic implementation detail.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif
}
@@ -727,7 +728,7 @@
testing::ExitedWithCode(0), "");
#endif
#else
- GTEST_LOG_(INFO) << "This tests a bionic extension.\n";
+ GTEST_SKIP() << "bionic extension";
#endif
}
@@ -739,7 +740,7 @@
limit = 32 * 1024 * 1024;
ASSERT_FALSE(android_mallopt(M_SET_ALLOCATION_LIMIT_BYTES, &limit, sizeof(limit)));
#else
- GTEST_LOG_(INFO) << "This tests a bionic extension.\n";
+ GTEST_SKIP() << "bionic extension";
#endif
}
@@ -804,7 +805,7 @@
VerifyMaxPointers(max_pointers);
#else
- GTEST_LOG_(INFO) << "This tests a bionic extension.\n";
+ GTEST_SKIP() << "bionic extension";
#endif
}
@@ -832,7 +833,7 @@
VerifyMaxPointers(max_pointers);
#else
- GTEST_LOG_(INFO) << "This tests a bionic extension.\n";
+ GTEST_SKIP() << "bionic extension";
#endif
}
@@ -852,7 +853,7 @@
VerifyMaxPointers(max_pointers);
#else
- GTEST_LOG_(INFO) << "This tests a bionic extension.\n";
+ GTEST_SKIP() << "bionic extension";
#endif
}
@@ -914,6 +915,6 @@
ASSERT_EQ(0, WEXITSTATUS(status));
}
#else
- GTEST_LOG_(INFO) << "This tests a bionic extension.\n";
+ GTEST_SKIP() << "bionic extension";
#endif
}
diff --git a/tests/math_test.cpp b/tests/math_test.cpp
index f816fad..1dd45b4 100644
--- a/tests/math_test.cpp
+++ b/tests/math_test.cpp
@@ -388,7 +388,7 @@
ASSERT_TRUE(__isnormal(123.0));
ASSERT_FALSE(__isnormal(double_subnormal()));
#else // __BIONIC__
- GTEST_LOG_(INFO) << "glibc doesn't have __isnormal.\n";
+ GTEST_SKIP() << "glibc doesn't have __isnormal";
#endif // __BIONIC__
}
@@ -397,7 +397,7 @@
ASSERT_TRUE(__isnormalf(123.0f));
ASSERT_FALSE(__isnormalf(float_subnormal()));
#else // __BIONIC__
- GTEST_LOG_(INFO) << "glibc doesn't have __isnormalf.\n";
+ GTEST_SKIP() << "glibc doesn't have __isnormalf";
#endif // __BIONIC__
}
@@ -406,7 +406,7 @@
ASSERT_TRUE(isnormalf(123.0f));
ASSERT_FALSE(isnormalf(float_subnormal()));
#else // __BIONIC__
- GTEST_LOG_(INFO) << "glibc doesn't have isnormalf.\n";
+ GTEST_SKIP() << "glibc doesn't have isnormalf";
#endif // __BIONIC__
}
@@ -415,7 +415,7 @@
ASSERT_TRUE(__isnormall(123.0L));
ASSERT_FALSE(__isnormall(ldouble_subnormal()));
#else // __BIONIC__
- GTEST_LOG_(INFO) << "glibc doesn't have __isnormall.\n";
+ GTEST_SKIP() << "glibc doesn't have __isnormall";
#endif // __BIONIC__
}
@@ -424,7 +424,7 @@
ASSERT_TRUE(isnormall(123.0L));
ASSERT_FALSE(isnormall(ldouble_subnormal()));
#else // __BIONIC__
- GTEST_LOG_(INFO) << "glibc doesn't have isnormall.\n";
+ GTEST_SKIP() << "glibc doesn't have isnormall";
#endif // __BIONIC__
}
@@ -1396,7 +1396,7 @@
ASSERT_DOUBLE_EQ(log(24.0), gamma_r(5.0, &sign));
ASSERT_EQ(1, sign);
#else // __BIONIC__
- GTEST_LOG_(INFO) << "glibc doesn't have gamma_r.\n";
+ GTEST_SKIP() << "glibc doesn't have gamma_r";
#endif // __BIONIC__
}
@@ -1406,7 +1406,7 @@
ASSERT_FLOAT_EQ(logf(24.0f), gammaf_r(5.0f, &sign));
ASSERT_EQ(1, sign);
#else // __BIONIC__
- GTEST_LOG_(INFO) << "glibc doesn't have gammaf_r.\n";
+ GTEST_SKIP() << "glibc doesn't have gammaf_r";
#endif // __BIONIC__
}
diff --git a/tests/membarrier_test.cpp b/tests/membarrier_test.cpp
index 9e871c7..6f650e7 100644
--- a/tests/membarrier_test.cpp
+++ b/tests/membarrier_test.cpp
@@ -46,8 +46,7 @@
TEST(membarrier, global_barrier) {
if (!HasMembarrier(MEMBARRIER_CMD_GLOBAL)) {
- GTEST_LOG_(INFO) << "MEMBARRIER_CMD_GLOBAL not supported, skipping test.";
- return;
+ GTEST_SKIP() << "MEMBARRIER_CMD_GLOBAL not supported";
}
ASSERT_EQ(0, syscall(__NR_membarrier, MEMBARRIER_CMD_GLOBAL, 0));
}
@@ -78,14 +77,10 @@
static void TestRegisterAndBarrierCommands(int membarrier_cmd_register,
int membarrier_cmd_barrier) {
if (!HasMembarrier(membarrier_cmd_register)) {
- GTEST_LOG_(INFO) << MembarrierCommandToName(membarrier_cmd_register)
- << " not supported, skipping test.";
- return;
+ GTEST_SKIP() << MembarrierCommandToName(membarrier_cmd_register) << " not supported";
}
if (!HasMembarrier(membarrier_cmd_barrier)) {
- GTEST_LOG_(INFO) << MembarrierCommandToName(membarrier_cmd_barrier)
- << " not supported, skipping test.";
- return;
+ GTEST_SKIP() << MembarrierCommandToName(membarrier_cmd_barrier) << " not supported";
}
ScopedErrnoCleaner errno_cleaner;
diff --git a/tests/pthread_test.cpp b/tests/pthread_test.cpp
index 973ca53..7b64401 100644
--- a/tests/pthread_test.cpp
+++ b/tests/pthread_test.cpp
@@ -190,7 +190,7 @@
ASSERT_EQ(EINVAL, pthread_setspecific(key, nullptr));
ASSERT_EQ(EINVAL, pthread_key_delete(key));
#else
- GTEST_LOG_(INFO) << "This test tests bionic pthread key implementation detail.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif
}
@@ -986,8 +986,7 @@
test_pthread_rwlock_reader_wakeup_writer(
[&](pthread_rwlock_t* lock) { return pthread_rwlock_timedwrlock_monotonic_np(lock, &ts); });
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing since pthread_rwlock_timedwrlock_monotonic_np is "
- "only supported on bionic";
+ GTEST_SKIP() << "pthread_rwlock_timedwrlock_monotonic_np not available";
#endif // __BIONIC__
}
@@ -1035,8 +1034,7 @@
test_pthread_rwlock_writer_wakeup_reader(
[&](pthread_rwlock_t* lock) { return pthread_rwlock_timedrdlock_monotonic_np(lock, &ts); });
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing since pthread_rwlock_timedrdlock_monotonic_np is "
- "only supported on bionic";
+ GTEST_SKIP() << "pthread_rwlock_timedrdlock_monotonic_np not available";
#endif // __BIONIC__
}
@@ -1096,8 +1094,7 @@
pthread_rwlock_timedrdlock_timeout_helper(CLOCK_MONOTONIC,
pthread_rwlock_timedrdlock_monotonic_np);
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing since pthread_rwlock_timedrdlock_monotonic_np is "
- "only supported on bionic";
+ GTEST_SKIP() << "pthread_rwlock_timedrdlock_monotonic_np not available";
#endif // __BIONIC__
}
@@ -1133,8 +1130,7 @@
pthread_rwlock_timedwrlock_timeout_helper(CLOCK_MONOTONIC,
pthread_rwlock_timedwrlock_monotonic_np);
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing since pthread_rwlock_timedwrlock_monotonic_np is "
- "only supported on bionic";
+ GTEST_SKIP() << "pthread_rwlock_timedwrlock_monotonic_np not available";
#endif // __BIONIC__
}
@@ -1364,7 +1360,7 @@
ASSERT_EQ(0, pthread_condattr_getpshared(&attr, &pshared));
ASSERT_EQ(PTHREAD_PROCESS_SHARED, pshared);
#else // !defined(__BIONIC__)
- GTEST_LOG_(INFO) << "This tests a bionic implementation detail.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif // !defined(__BIONIC__)
}
@@ -1480,8 +1476,7 @@
progress = SIGNALED;
ASSERT_EQ(0, pthread_cond_signal(&cond));
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing since pthread_cond_timedwait_monotonic_np is only "
- "supported on bionic";
+ GTEST_SKIP() << "pthread_cond_timedwait_monotonic_np not available";
#endif // __BIONIC__
}
@@ -1516,8 +1511,7 @@
#if defined(__BIONIC__)
pthread_cond_timedwait_timeout_helper(CLOCK_MONOTONIC, pthread_cond_timedwait_monotonic_np);
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing since pthread_cond_timedwait_monotonic_np is only "
- "supported on bionic";
+ GTEST_SKIP() << "pthread_cond_timedwait_monotonic_np not available";
#endif // __BIONIC__
}
@@ -1739,7 +1733,7 @@
ASSERT_EQ(t_gettid_result, t_pthread_gettid_np_result);
#else
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "pthread_gettid_np not available";
#endif
}
@@ -1934,7 +1928,7 @@
}
ASSERT_EQ(0, pthread_mutexattr_destroy(&attr));
#else
- GTEST_LOG_(INFO) << "This test does nothing as pi mutex count isn't limited.\n";
+ GTEST_SKIP() << "pi mutex count not limited to 64Ki";
#endif
}
@@ -2121,7 +2115,7 @@
// Bionic's pthread_mutex implementation on 32-bit devices uses 16 bits to represent owner tid.
ASSERT_LE(pid_max, 65536);
#else
- GTEST_LOG_(INFO) << "This test does nothing as 32-bit tid is supported by pthread_mutex.\n";
+ GTEST_SKIP() << "pthread_mutex supports 32-bit tid";
#endif
}
@@ -2164,8 +2158,7 @@
#if defined(__BIONIC__)
pthread_mutex_timedlock_helper(CLOCK_MONOTONIC, pthread_mutex_timedlock_monotonic_np);
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing since pthread_mutex_timedlock_monotonic_np is only "
- "supported on bionic";
+ GTEST_SKIP() << "pthread_mutex_timedlock_monotonic_np not available";
#endif // __BIONIC__
}
@@ -2216,8 +2209,7 @@
#if defined(__BIONIC__)
pthread_mutex_timedlock_pi_helper(CLOCK_MONOTONIC, pthread_mutex_timedlock_monotonic_np);
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing since pthread_mutex_timedlock_monotonic_np is only "
- "supported on bionic";
+ GTEST_SKIP() << "pthread_mutex_timedlock_monotonic_np not available";
#endif // __BIONIC__
}
@@ -2240,7 +2232,7 @@
ASSERT_EXIT(pthread_mutex_destroy(&m), ::testing::KilledBySignal(SIGABRT),
"pthread_mutex_destroy called on a destroyed mutex");
#else
- GTEST_LOG_(INFO) << "This test tests bionic pthread mutex implementation details.";
+ GTEST_SKIP() << "bionic-only test";
#endif
}
@@ -2297,7 +2289,7 @@
ASSERT_EQ(0, pthread_rwlock_destroy(rwlock));
#else
- GTEST_LOG_(INFO) << "This test tests bionic implementation details.";
+ GTEST_SKIP() << "bionic-only test";
#endif
}
@@ -2312,7 +2304,7 @@
pthread_mutex_t* null_value = nullptr;
ASSERT_EQ(EINVAL, pthread_mutex_lock(null_value));
#else
- GTEST_LOG_(INFO) << "This test tests bionic implementation details on 32 bit devices.";
+ GTEST_SKIP() << "32-bit bionic-only test";
#endif
}
@@ -2327,7 +2319,7 @@
pthread_mutex_t* null_value = nullptr;
ASSERT_EQ(EINVAL, pthread_mutex_unlock(null_value));
#else
- GTEST_LOG_(INFO) << "This test tests bionic implementation details on 32 bit devices.";
+ GTEST_SKIP() << "32-bit bionic-only test";
#endif
}
@@ -2336,7 +2328,7 @@
pthread_mutex_t* null_value = nullptr;
ASSERT_EXIT(pthread_mutex_lock(null_value), testing::KilledBySignal(SIGSEGV), "");
#else
- GTEST_LOG_(INFO) << "This test tests bionic implementation details on 64 bit devices.";
+ GTEST_SKIP() << "64-bit bionic-only test";
#endif
}
@@ -2345,7 +2337,7 @@
pthread_mutex_t* null_value = nullptr;
ASSERT_EXIT(pthread_mutex_unlock(null_value), testing::KilledBySignal(SIGSEGV), "");
#else
- GTEST_LOG_(INFO) << "This test tests bionic implementation details on 64 bit devices.";
+ GTEST_SKIP() << "64-bit bionic-only test";
#endif
}
@@ -2658,10 +2650,7 @@
TEST(pthread, pthread_attr_setinheritsched_PTHREAD_INHERIT_SCHED_takes_effect) {
sched_param param = { .sched_priority = sched_get_priority_min(SCHED_FIFO) };
int rc = pthread_setschedparam(pthread_self(), SCHED_FIFO, ¶m);
- if (rc == EPERM) {
- GTEST_LOG_(INFO) << "pthread_setschedparam failed with EPERM, skipping test\n";
- return;
- }
+ if (rc == EPERM) GTEST_SKIP() << "pthread_setschedparam failed with EPERM";
ASSERT_EQ(0, rc);
pthread_attr_t attr;
@@ -2682,10 +2671,7 @@
TEST(pthread, pthread_attr_setinheritsched_PTHREAD_EXPLICIT_SCHED_takes_effect) {
sched_param param = { .sched_priority = sched_get_priority_min(SCHED_FIFO) };
int rc = pthread_setschedparam(pthread_self(), SCHED_FIFO, ¶m);
- if (rc == EPERM) {
- GTEST_LOG_(INFO) << "pthread_setschedparam failed with EPERM, skipping test\n";
- return;
- }
+ if (rc == EPERM) GTEST_SKIP() << "pthread_setschedparam failed with EPERM";
ASSERT_EQ(0, rc);
pthread_attr_t attr;
@@ -2707,10 +2693,7 @@
TEST(pthread, pthread_attr_setinheritsched__takes_effect_despite_SCHED_RESET_ON_FORK) {
sched_param param = { .sched_priority = sched_get_priority_min(SCHED_FIFO) };
int rc = pthread_setschedparam(pthread_self(), SCHED_FIFO | SCHED_RESET_ON_FORK, ¶m);
- if (rc == EPERM) {
- GTEST_LOG_(INFO) << "pthread_setschedparam failed with EPERM, skipping test\n";
- return;
- }
+ if (rc == EPERM) GTEST_SKIP() << "pthread_setschedparam failed with EPERM";
ASSERT_EQ(0, rc);
pthread_attr_t attr;
diff --git a/tests/pty_test.cpp b/tests/pty_test.cpp
index 75f228c..29f86f1 100644
--- a/tests/pty_test.cpp
+++ b/tests/pty_test.cpp
@@ -109,8 +109,7 @@
cpu_set_t cpus;
ASSERT_EQ(0, sched_getaffinity(0, sizeof(cpu_set_t), &cpus));
if (CPU_COUNT(&cpus) < 2) {
- GTEST_LOG_(INFO) << "This test tests bug happens only on multiprocessors.";
- return;
+ GTEST_SKIP() << "This bug only happens on multiprocessors";
}
constexpr uint32_t TEST_DATA_COUNT = 2000000;
diff --git a/tests/run-on-host.sh b/tests/run-on-host.sh
index c47bc4f..c8a30f5 100755
--- a/tests/run-on-host.sh
+++ b/tests/run-on-host.sh
@@ -3,32 +3,33 @@
. $(dirname $0)/../build/run-on-host.sh
if [ "$1" = glibc ]; then
- m -j bionic-unit-tests-glibc
- (
- cd ${ANDROID_BUILD_TOP}
- export ANDROID_DATA=${TARGET_OUT_DATA}
- export ANDROID_ROOT=${TARGET_OUT}
- ${HOST_OUT}/nativetest64/bionic-unit-tests-glibc/bionic-unit-tests-glibc $@
- )
- exit 0
+ shift
+ m -j bionic-unit-tests-glibc
+ (
+ cd ${ANDROID_BUILD_TOP}
+ export ANDROID_DATA=${TARGET_OUT_DATA}
+ export ANDROID_ROOT=${TARGET_OUT}
+ ${HOST_OUT}/nativetest64/bionic-unit-tests-glibc/bionic-unit-tests-glibc $@
+ )
+ exit 0
elif [ "$1" != 32 -a "$1" != 64 ]; then
- echo "Usage: $0 [ 32 | 64 | glibc ] [gtest flags]"
- exit 1
+ echo "Usage: $0 [ 32 | 64 | glibc ] [gtest flags]"
+ exit 1
fi
if [ ${HOST_OS}-${HOST_ARCH} = linux-x86 -o ${HOST_OS}-${HOST_ARCH} = linux-x86_64 ]; then
- prepare $1 bionic-unit-tests
+ prepare $1 bionic-unit-tests
- if [ ${TARGET_ARCH} = x86 -o ${TARGET_ARCH} = x86_64 ]; then
- (
- cd ${ANDROID_BUILD_TOP}
- export ANDROID_DATA=${TARGET_OUT_DATA}
- export ANDROID_DNS_MODE=local
- export ANDROID_ROOT=${TARGET_OUT}
- ${NATIVETEST}/bionic-unit-tests/bionic-unit-tests $@
- )
- else
- echo "$0 not supported on TARGET_ARCH=$TARGET_ARCH"
- fi
+ if [ ${TARGET_ARCH} = x86 -o ${TARGET_ARCH} = x86_64 ]; then
+ (
+ cd ${ANDROID_BUILD_TOP}
+ export ANDROID_DATA=${TARGET_OUT_DATA}
+ export ANDROID_DNS_MODE=local
+ export ANDROID_ROOT=${TARGET_OUT}
+ ${NATIVETEST}/bionic-unit-tests/bionic-unit-tests $@
+ )
+ else
+ echo "$0 not supported on TARGET_ARCH=$TARGET_ARCH"
+ fi
fi
diff --git a/tests/sched_test.cpp b/tests/sched_test.cpp
index 9184026..9309a7f 100644
--- a/tests/sched_test.cpp
+++ b/tests/sched_test.cpp
@@ -47,7 +47,7 @@
// See https://sourceware.org/bugzilla/show_bug.cgi?id=10311 for more details.
TEST(sched, clone) {
// In order to enumerate all possible tests for CTS, create an empty test.
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "glibc is broken";
}
#endif
diff --git a/tests/semaphore_test.cpp b/tests/semaphore_test.cpp
index 690e886..7addf6d 100644
--- a/tests/semaphore_test.cpp
+++ b/tests/semaphore_test.cpp
@@ -141,8 +141,7 @@
#if defined(__BIONIC__)
sem_timedwait_helper(CLOCK_MONOTONIC, sem_timedwait_monotonic_np);
#else // __BIONIC__
- GTEST_LOG_(INFO)
- << "This test does nothing since sem_timedwait_monotonic_np is only supported on bionic";
+ GTEST_SKIP() << "sem_timedwait_monotonic_np is only supported on bionic";
#endif // __BIONIC__
}
@@ -218,7 +217,7 @@
ASSERT_EQ(0, pthread_join(thread, &result));
ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(result));
#else
- GTEST_LOG_(INFO) << "This test tests sem_wait's compatibility for old sdk versions";
+ GTEST_SKIP() << "This test tests sem_wait's compatibility for old sdk versions";
#endif
}
diff --git a/tests/signal_test.cpp b/tests/signal_test.cpp
index 77b004f..1ae174a 100644
--- a/tests/signal_test.cpp
+++ b/tests/signal_test.cpp
@@ -582,7 +582,7 @@
ASSERT_TRUE(sys_signame[0] == nullptr);
ASSERT_STREQ("HUP", sys_signame[SIGHUP]);
#else
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "glibc doesn't have sys_signame";
#endif
}
diff --git a/tests/stack_protector_test.cpp b/tests/stack_protector_test.cpp
index 7a85cc3..9fe7bb1 100644
--- a/tests/stack_protector_test.cpp
+++ b/tests/stack_protector_test.cpp
@@ -95,7 +95,7 @@
ASSERT_NE(0, gettid());
ASSERT_NE(0U, __stack_chk_guard);
#else
- GTEST_LOG_(INFO) << "glibc doesn't have a global __stack_chk_guard.\n";
+ GTEST_SKIP() << "glibc doesn't have a global __stack_chk_guard";
#endif
}
diff --git a/tests/stdio_ext_test.cpp b/tests/stdio_ext_test.cpp
index d84fda0..fce600a 100644
--- a/tests/stdio_ext_test.cpp
+++ b/tests/stdio_ext_test.cpp
@@ -193,7 +193,7 @@
TEST(stdio_ext, __fseterr) {
#if defined(__GLIBC__)
- GTEST_LOG_(INFO) << "glibc doesn't have __fseterr, but gnulib will use it";
+ GTEST_SKIP() << "glibc doesn't have __fseterr, but gnulib will use it";
#else
FILE* fp = fopen("/dev/null", "w");
diff --git a/tests/stdio_test.cpp b/tests/stdio_test.cpp
index ad6ed45..65a942c 100644
--- a/tests/stdio_test.cpp
+++ b/tests/stdio_test.cpp
@@ -330,7 +330,7 @@
int i = 1234;
EXPECT_DEATH(snprintf(buf, sizeof(buf), "a %n b", &i), "%n not allowed on Android");
#else
- GTEST_LOG_(INFO) << "This test does nothing on glibc.\n";
+ GTEST_SKIP() << "glibc does allow %n";
#endif
}
@@ -1897,7 +1897,7 @@
ASSERT_EQ(nullptr, open_memstream(&p, nullptr));
ASSERT_EQ(EINVAL, errno);
#else
- GTEST_LOG_(INFO) << "This test does nothing on glibc.\n";
+ GTEST_SKIP() << "glibc is broken";
#endif
}
@@ -2157,7 +2157,7 @@
fclose(fp);
#else
- GTEST_LOG_(INFO) << "glibc uses fopencookie instead.\n";
+ GTEST_SKIP() << "glibc uses fopencookie instead";
#endif
}
@@ -2167,7 +2167,7 @@
ASSERT_EQ(nullptr, funopen(nullptr, nullptr, nullptr, nullptr, nullptr));
ASSERT_EQ(EINVAL, errno);
#else
- GTEST_LOG_(INFO) << "glibc uses fopencookie instead.\n";
+ GTEST_SKIP() << "glibc uses fopencookie instead";
#endif
}
@@ -2195,7 +2195,7 @@
EXPECT_EQ(0, fgetpos64(fp64, &pos64)) << strerror(errno);
EXPECT_EQ(0xfedcba12345678, pos64);
#else
- GTEST_LOG_(INFO) << "glibc uses fopencookie instead.\n";
+ GTEST_SKIP() << "glibc uses fopencookie instead";
#endif
}
@@ -2234,7 +2234,7 @@
EXPECT_EQ(offset, static_cast<off64_t>(pos));
EXPECT_EQ(offset, static_cast<off64_t>(pos64));
#else
- GTEST_LOG_(INFO) << "glibc's fpos_t is opaque.\n";
+ GTEST_SKIP() << "glibc's fpos_t is opaque";
#endif
}
diff --git a/tests/string_test.cpp b/tests/string_test.cpp
index b27ca87..335d33b 100644
--- a/tests/string_test.cpp
+++ b/tests/string_test.cpp
@@ -85,7 +85,7 @@
ASSERT_STREQ("Unknown error 1001", strerror1001);
#else // __BIONIC__
- GTEST_LOG_(INFO) << "Skipping test, requires a thread safe strerror.";
+ GTEST_SKIP() << "thread-safe strerror not available";
#endif // __BIONIC__
}
@@ -578,7 +578,7 @@
}
}
#else
- GTEST_LOG_(INFO) << "Skipping test, strlcat not supported on this platform.";
+ GTEST_SKIP() << "strlcat not available";
#endif
}
@@ -610,7 +610,7 @@
(memcmp(state.ptr2, state.ptr + state.MAX_LEN, state.MAX_LEN) != 0));
}
#else
- GTEST_LOG_(INFO) << "Skipping test, strlcpy not supported on this platform.";
+ GTEST_SKIP() << "strlcpy not available";
#endif
}
@@ -1139,7 +1139,7 @@
#if defined(STRLCPY_SUPPORTED)
RunSrcDstBufferAlignTest(LARGE, DoStrlcpyTest);
#else
- GTEST_LOG_(INFO) << "Skipping test, strlcpy not supported on this platform.";
+ GTEST_SKIP() << "strlcpy not available";
#endif
}
@@ -1147,7 +1147,7 @@
#if defined(STRLCPY_SUPPORTED)
RunSrcDstBufferOverreadTest(DoStrlcpyTest);
#else
- GTEST_LOG_(INFO) << "Skipping test, strlcpy not supported on this platform.";
+ GTEST_SKIP() << "strlcpy not available";
#endif
}
@@ -1275,7 +1275,7 @@
#if defined(STRLCAT_SUPPORTED)
RunSrcDstBufferAlignTest(MEDIUM, DoStrlcatTest, LargeSetIncrement);
#else
- GTEST_LOG_(INFO) << "Skipping test, strlcat not supported on this platform.";
+ GTEST_SKIP() << "strlcat not available";
#endif
}
@@ -1283,7 +1283,7 @@
#if defined(STRLCAT_SUPPORTED)
RunSrcDstBufferOverreadTest(DoStrlcatTest);
#else
- GTEST_LOG_(INFO) << "Skipping test, strlcat not supported on this platform.";
+ GTEST_SKIP() << "strlcat not available";
#endif
}
diff --git a/tests/sys_msg_test.cpp b/tests/sys_msg_test.cpp
index 8b3623e..200f654 100644
--- a/tests/sys_msg_test.cpp
+++ b/tests/sys_msg_test.cpp
@@ -35,8 +35,7 @@
TEST(sys_msg, smoke) {
if (msgctl(-1, IPC_STAT, nullptr) == -1 && errno == ENOSYS) {
- GTEST_LOG_(INFO) << "no <sys/msg.h> support in this kernel\n";
- return;
+ GTEST_SKIP() << "no <sys/msg.h> support in this kernel";
}
// Create a queue.
diff --git a/tests/sys_param_test.cpp b/tests/sys_param_test.cpp
new file mode 100644
index 0000000..e4bbf42
--- /dev/null
+++ b/tests/sys_param_test.cpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gtest/gtest.h>
+#include <sys/param.h>
+
+TEST(sys_param_test, powerof2_positives) {
+ ASSERT_TRUE(powerof2(1));
+ ASSERT_TRUE(powerof2(2));
+ ASSERT_TRUE(powerof2(4));
+ ASSERT_TRUE(powerof2(8));
+ ASSERT_FALSE(powerof2(3));
+ ASSERT_FALSE(powerof2(5));
+ ASSERT_FALSE(powerof2(7));
+ ASSERT_FALSE(powerof2(9));
+ ASSERT_FALSE(powerof2(10));
+}
+
+TEST(sys_param_test, powerof2_zero) {
+ // 0 isn't a power of 2, but for compatibility, we assume it is.
+ ASSERT_TRUE(powerof2(0));
+ uint32_t zero = 0;
+ ASSERT_TRUE(powerof2(zero));
+}
+
+TEST(sys_param_test, powerof2_negatives) {
+ // negative numbers can never be a power of 2, but for compatibility,
+ // we assume they can be.
+ int32_t min32 = INT32_MIN;
+ int64_t min64 = INT64_MIN;
+ ASSERT_TRUE(powerof2(min32));
+ ASSERT_FALSE(powerof2(min32 + 1));
+ ASSERT_TRUE(powerof2(min64));
+ ASSERT_FALSE(powerof2(min64 + 1));
+}
diff --git a/tests/sys_prctl_test.cpp b/tests/sys_prctl_test.cpp
index cd23c0a..6d1fa1d 100644
--- a/tests/sys_prctl_test.cpp
+++ b/tests/sys_prctl_test.cpp
@@ -61,7 +61,7 @@
ASSERT_EQ(0, munmap(p, page_size * 3));
#else
- GTEST_LOG_(INFO) << "This test does nothing as it tests an Android specific kernel feature.";
+ GTEST_SKIP() << "PR_SET_VMA not available";
#endif
}
@@ -112,7 +112,6 @@
EXPECT_EQ(-1, err);
EXPECT_EQ(EINVAL, errno);
#else
- GTEST_LOG_(INFO)
- << "Skipping test that requires host support for PR_CAP_AMBIENT.";
+ GTEST_SKIP() << "PR_CAP_AMBIENT not available";
#endif
}
diff --git a/tests/sys_ptrace_test.cpp b/tests/sys_ptrace_test.cpp
index 04dcd4e..9b3dba0 100644
--- a/tests/sys_ptrace_test.cpp
+++ b/tests/sys_ptrace_test.cpp
@@ -62,14 +62,13 @@
enum class HwFeature { Watchpoint, Breakpoint };
-static bool is_hw_feature_supported(pid_t child, HwFeature feature) {
+static void check_hw_feature_supported(pid_t child, HwFeature feature) {
#if defined(__arm__)
long capabilities;
long result = ptrace(PTRACE_GETHBPREGS, child, 0, &capabilities);
if (result == -1) {
EXPECT_EQ(EIO, errno);
- GTEST_LOG_(INFO) << "Hardware debug support disabled at kernel configuration time.";
- return false;
+ GTEST_SKIP() << "Hardware debug support disabled at kernel configuration time";
}
uint8_t hb_count = capabilities & 0xff;
capabilities >>= 8;
@@ -77,19 +76,12 @@
capabilities >>= 8;
uint8_t max_wp_size = capabilities & 0xff;
if (max_wp_size == 0) {
- GTEST_LOG_(INFO)
- << "Kernel reports zero maximum watchpoint size. Hardware debug support missing.";
- return false;
+ GTEST_SKIP() << "Kernel reports zero maximum watchpoint size";
+ } else if (feature == HwFeature::Watchpoint && wp_count == 0) {
+ GTEST_SKIP() << "Kernel reports zero hardware watchpoints";
+ } else if (feature == HwFeature::Breakpoint && hb_count == 0) {
+ GTEST_SKIP() << "Kernel reports zero hardware breakpoints";
}
- if (feature == HwFeature::Watchpoint && wp_count == 0) {
- GTEST_LOG_(INFO) << "Kernel reports zero hardware watchpoints";
- return false;
- }
- if (feature == HwFeature::Breakpoint && hb_count == 0) {
- GTEST_LOG_(INFO) << "Kernel reports zero hardware breakpoints";
- return false;
- }
- return true;
#elif defined(__aarch64__)
user_hwdebug_state dreg_state;
iovec iov;
@@ -99,20 +91,13 @@
long result = ptrace(PTRACE_GETREGSET, child,
feature == HwFeature::Watchpoint ? NT_ARM_HW_WATCH : NT_ARM_HW_BREAK, &iov);
if (result == -1) {
- EXPECT_EQ(EINVAL, errno);
- return false;
+ ASSERT_EQ(EINVAL, errno);
}
- return (dreg_state.dbg_info & 0xff) > 0;
-#elif defined(__i386__) || defined(__x86_64__)
+ if ((dreg_state.dbg_info & 0xff) == 0) GTEST_SKIP() << "hardware support missing";
+#else
// We assume watchpoints and breakpoints are always supported on x86.
UNUSED(child);
UNUSED(feature);
- return true;
-#else
- // TODO: mips support.
- UNUSED(child);
- UNUSED(feature);
- return false;
#endif
}
@@ -190,10 +175,7 @@
ASSERT_TRUE(WIFSTOPPED(status)) << "Status was: " << status;
ASSERT_EQ(SIGSTOP, WSTOPSIG(status)) << "Status was: " << status;
- if (!is_hw_feature_supported(child, HwFeature::Watchpoint)) {
- GTEST_LOG_(INFO) << "Skipping test because hardware support is not available.\n";
- return;
- }
+ check_hw_feature_supported(child, HwFeature::Watchpoint);
set_watchpoint(child, uintptr_t(untag_address(&data)) + offset, size);
@@ -360,10 +342,7 @@
ASSERT_TRUE(WIFSTOPPED(status)) << "Status was: " << status;
ASSERT_EQ(SIGSTOP, WSTOPSIG(status)) << "Status was: " << status;
- if (!is_hw_feature_supported(child, HwFeature::Breakpoint)) {
- GTEST_LOG_(INFO) << "Skipping test because hardware support is not available.\n";
- return;
- }
+ check_hw_feature_supported(child, HwFeature::Breakpoint);
set_breakpoint(child);
diff --git a/tests/sys_random_test.cpp b/tests/sys_random_test.cpp
index 78cbf4a..2e2665b 100644
--- a/tests/sys_random_test.cpp
+++ b/tests/sys_random_test.cpp
@@ -43,7 +43,7 @@
ASSERT_EQ(0, getentropy(buf2, sizeof(buf2)));
ASSERT_TRUE(memcmp(buf1, buf2, sizeof(buf1)) != 0);
#else
- GTEST_LOG_(INFO) << "This test requires a C library with <sys/random.h>.\n";
+ GTEST_SKIP() << "<sys/random.h> not available";
#endif
}
@@ -53,7 +53,7 @@
ASSERT_EQ(-1, getentropy(nullptr, 1));
ASSERT_EQ(EFAULT, errno);
#else
- GTEST_LOG_(INFO) << "This test requires a C library with <sys/random.h>.\n";
+ GTEST_SKIP() << "<sys/random.h> not available";
#endif
}
@@ -66,7 +66,7 @@
ASSERT_EQ(-1, getentropy(buf, sizeof(buf)));
ASSERT_EQ(EIO, errno);
#else
- GTEST_LOG_(INFO) << "This test requires a C library with <sys/random.h>.\n";
+ GTEST_SKIP() << "<sys/random.h> not available";
#endif
}
@@ -79,7 +79,7 @@
ASSERT_EQ(64, getrandom(buf2, sizeof(buf2), 0));
ASSERT_TRUE(memcmp(buf1, buf2, sizeof(buf1)) != 0);
#else
- GTEST_LOG_(INFO) << "This test requires a C library with <sys/random.h>.\n";
+ GTEST_SKIP() << "<sys/random.h> not available";
#endif
}
@@ -89,7 +89,7 @@
ASSERT_EQ(-1, getrandom(nullptr, 256, 0));
ASSERT_EQ(EFAULT, errno);
#else
- GTEST_LOG_(INFO) << "This test requires a C library with <sys/random.h>.\n";
+ GTEST_SKIP() << "<sys/random.h> not available";
#endif
}
@@ -100,6 +100,6 @@
ASSERT_EQ(-1, getrandom(buf, sizeof(buf), ~0));
ASSERT_EQ(EINVAL, errno);
#else
- GTEST_LOG_(INFO) << "This test requires a C library with <sys/random.h>.\n";
+ GTEST_SKIP() << "<sys/random.h> not available";
#endif
}
diff --git a/tests/sys_sem_test.cpp b/tests/sys_sem_test.cpp
index dff34c8..b98926b 100644
--- a/tests/sys_sem_test.cpp
+++ b/tests/sys_sem_test.cpp
@@ -35,8 +35,7 @@
TEST(sys_sem, smoke) {
if (semctl(-1, 0, IPC_RMID) == -1 && errno == ENOSYS) {
- GTEST_LOG_(INFO) << "no <sys/sem.h> support in this kernel\n";
- return;
+ GTEST_SKIP() << "no <sys/sem.h> support in this kernel";
}
// Create a semaphore.
diff --git a/tests/sys_shm_test.cpp b/tests/sys_shm_test.cpp
index 15abe05..fd5d424 100644
--- a/tests/sys_shm_test.cpp
+++ b/tests/sys_shm_test.cpp
@@ -34,8 +34,7 @@
TEST(sys_shm, smoke) {
if (shmctl(-1, IPC_STAT, nullptr) == -1 && errno == ENOSYS) {
- GTEST_LOG_(INFO) << "no <sys/shm.h> support in this kernel\n";
- return;
+ GTEST_SKIP() << "no <sys/shm.h> support in this kernel";
}
// Create a segment.
diff --git a/tests/sys_stat_test.cpp b/tests/sys_stat_test.cpp
index 70ad451..97bf580 100644
--- a/tests/sys_stat_test.cpp
+++ b/tests/sys_stat_test.cpp
@@ -82,7 +82,7 @@
unlink(path.c_str());
} else {
// SELinux policy forbids us from creating FIFOs. http://b/17646702.
- GTEST_LOG_(INFO) << "This test only performs a test when run as root.";
+ GTEST_SKIP() << "SELinux policy forbids non-root from creating FIFOs";
}
}
diff --git a/tests/system_properties_test.cpp b/tests/system_properties_test.cpp
index 3b50896..245e42f 100644
--- a/tests/system_properties_test.cpp
+++ b/tests/system_properties_test.cpp
@@ -121,7 +121,7 @@
ASSERT_EQ(5, system_properties.Get(name, propvalue));
ASSERT_STREQ(propvalue, "value");
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif // __BIONIC__
}
@@ -156,7 +156,7 @@
ASSERT_EQ(6, system_properties.Get("property_other", propvalue));
ASSERT_STREQ(propvalue, "value6");
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif // __BIONIC__
}
@@ -202,7 +202,7 @@
ASSERT_EQ(0, memcmp(prop_value, prop_value_ret, PROP_VALUE_MAX));
}
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif // __BIONIC__
}
@@ -219,7 +219,7 @@
ASSERT_EQ(0, system_properties.Foreach(foreach_test_callback, &count));
ASSERT_EQ(3U, count);
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif // __BIONIC__
}
@@ -248,7 +248,7 @@
ASSERT_TRUE(system_properties.FindNth(i) == nullptr);
}
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif // __BIONIC__
}
@@ -307,7 +307,7 @@
}
}
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif // __BIONIC__
}
@@ -328,7 +328,7 @@
ASSERT_EQ(-1, system_properties.Add("name", 4, "value", PROP_VALUE_MAX));
ASSERT_EQ(-1, system_properties.Update(NULL, "value", PROP_VALUE_MAX));
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif // __BIONIC__
}
@@ -344,7 +344,7 @@
ASSERT_EQ(0, system_properties.Update(const_cast<prop_info*>(pi), "value2", 6));
ASSERT_NE(serial, system_properties.Serial(pi));
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif // __BIONIC__
}
@@ -375,7 +375,7 @@
thread.join();
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif // __BIONIC__
}
@@ -408,7 +408,7 @@
thread.join();
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif // __BIONIC__
}
@@ -436,7 +436,7 @@
ASSERT_EXIT(__system_property_add("property", 8, "value", 5), KilledByFault(), "");
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif // __BIONIC__
}
@@ -508,7 +508,7 @@
}
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif // __BIONIC__
}
@@ -523,6 +523,6 @@
ASSERT_NE(0, system_properties.Add(name.c_str(), name.size(), value.c_str(), value.size()));
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif // __BIONIC__
}
diff --git a/tests/system_properties_test2.cpp b/tests/system_properties_test2.cpp
index e6e7ef2..c061faa 100644
--- a/tests/system_properties_test2.cpp
+++ b/tests/system_properties_test2.cpp
@@ -124,7 +124,7 @@
ASSERT_EQ(expected_name, legacy_name);
ASSERT_STREQ("value2", propvalue);
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif // __BIONIC__
}
@@ -143,6 +143,6 @@
}
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif // __BIONIC__
}
diff --git a/tests/time_test.cpp b/tests/time_test.cpp
index 50830ee..c890358 100644
--- a/tests/time_test.cpp
+++ b/tests/time_test.cpp
@@ -296,6 +296,69 @@
EXPECT_STREQ("09:41:53", buf);
}
+TEST(time, strptime_F) {
+ setenv("TZ", "UTC", 1);
+
+ struct tm tm = {};
+ ASSERT_EQ('\0', *strptime("2019-03-26", "%F", &tm));
+ EXPECT_EQ(119, tm.tm_year);
+ EXPECT_EQ(2, tm.tm_mon);
+ EXPECT_EQ(26, tm.tm_mday);
+}
+
+TEST(time, strptime_P_p) {
+ setenv("TZ", "UTC", 1);
+
+ // For parsing, %P and %p are the same: case doesn't matter.
+
+ struct tm tm = {.tm_hour = 12};
+ ASSERT_EQ('\0', *strptime("AM", "%p", &tm));
+ EXPECT_EQ(0, tm.tm_hour);
+
+ tm = {.tm_hour = 12};
+ ASSERT_EQ('\0', *strptime("am", "%p", &tm));
+ EXPECT_EQ(0, tm.tm_hour);
+
+ tm = {.tm_hour = 12};
+ ASSERT_EQ('\0', *strptime("AM", "%P", &tm));
+ EXPECT_EQ(0, tm.tm_hour);
+
+ tm = {.tm_hour = 12};
+ ASSERT_EQ('\0', *strptime("am", "%P", &tm));
+ EXPECT_EQ(0, tm.tm_hour);
+}
+
+TEST(time, strptime_u) {
+ setenv("TZ", "UTC", 1);
+
+ struct tm tm = {};
+ ASSERT_EQ('\0', *strptime("2", "%u", &tm));
+ EXPECT_EQ(2, tm.tm_wday);
+}
+
+TEST(time, strptime_v) {
+ setenv("TZ", "UTC", 1);
+
+ struct tm tm = {};
+ ASSERT_EQ('\0', *strptime("26-Mar-1980", "%v", &tm));
+ EXPECT_EQ(80, tm.tm_year);
+ EXPECT_EQ(2, tm.tm_mon);
+ EXPECT_EQ(26, tm.tm_mday);
+}
+
+TEST(time, strptime_V_G_g) {
+ setenv("TZ", "UTC", 1);
+
+ // %V (ISO-8601 week number), %G (year of week number, without century), and
+ // %g (year of week number) have no effect when parsed, and are supported
+ // solely so that it's possible for strptime(3) to parse everything that
+ // strftime(3) can output.
+ struct tm tm = {};
+ ASSERT_EQ('\0', *strptime("1 2 3", "%V %G %g", &tm));
+ struct tm zero = {};
+ EXPECT_TRUE(memcmp(&tm, &zero, sizeof(tm)) == 0);
+}
+
void SetTime(timer_t t, time_t value_s, time_t value_ns, time_t interval_s, time_t interval_ns) {
itimerspec ts;
ts.it_value.tv_sec = value_s;
@@ -912,6 +975,6 @@
ASSERT_EQ(0, timespec_get(&ts, 123));
ASSERT_EQ(TIME_UTC, timespec_get(&ts, TIME_UTC));
#else
- GTEST_LOG_(INFO) << "glibc doesn't have timespec_get until 2.21\n";
+ GTEST_SKIP() << "glibc doesn't have timespec_get until 2.21";
#endif
}
diff --git a/tests/utils.h b/tests/utils.h
index cc1aa8c..fe41019 100644
--- a/tests/utils.h
+++ b/tests/utils.h
@@ -64,7 +64,7 @@
return &__hwasan_init != 0;
}
-#define SKIP_WITH_HWASAN if (running_with_hwasan()) { return; }
+#define SKIP_WITH_HWASAN if (running_with_hwasan()) GTEST_SKIP()
static inline void* untag_address(void* addr) {
#if defined(__LP64__)
diff --git a/tests/wchar_test.cpp b/tests/wchar_test.cpp
index 9aef800..9b4fc4f 100644
--- a/tests/wchar_test.cpp
+++ b/tests/wchar_test.cpp
@@ -713,7 +713,7 @@
ASSERT_EQ(nullptr, open_wmemstream(&p, nullptr));
ASSERT_EQ(EINVAL, errno);
#else
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "This test is bionic-specific";
#endif
}
diff --git a/tests/wctype_test.cpp b/tests/wctype_test.cpp
index 06e1571..85a46aa 100644
--- a/tests/wctype_test.cpp
+++ b/tests/wctype_test.cpp
@@ -111,7 +111,7 @@
EXPECT_EQ(wint_t(L'δ'), towlower(L'δ'));
EXPECT_EQ(wint_t(L'δ'), towlower(L'Δ'));
} else {
- GTEST_LOG_(INFO) << "skipping unicode towlower tests";
+ GTEST_SKIP() << "icu not available";
}
}
@@ -127,7 +127,7 @@
EXPECT_EQ(wint_t(L'δ'), towlower_l(L'δ', l.l));
EXPECT_EQ(wint_t(L'δ'), towlower_l(L'Δ', l.l));
} else {
- GTEST_LOG_(INFO) << "skipping unicode towlower_l tests";
+ GTEST_SKIP() << "icu not available";
}
}
@@ -142,7 +142,7 @@
EXPECT_EQ(wint_t(L'Δ'), towupper(L'δ'));
EXPECT_EQ(wint_t(L'Δ'), towupper(L'Δ'));
} else {
- GTEST_LOG_(INFO) << "skipping unicode towupper tests";
+ GTEST_SKIP() << "icu not available";
}
}
@@ -158,7 +158,7 @@
EXPECT_EQ(wint_t(L'Δ'), towupper_l(L'δ', l.l));
EXPECT_EQ(wint_t(L'Δ'), towupper_l(L'Δ', l.l));
} else {
- GTEST_LOG_(INFO) << "skipping unicode towupper_l tests";
+ GTEST_SKIP() << "icu not available";
}
}