Merge "Fix posix_spawn signal defaulting."
diff --git a/docs/32-bit-abi.md b/docs/32-bit-abi.md
index 5e3ae45..9ae1973 100644
--- a/docs/32-bit-abi.md
+++ b/docs/32-bit-abi.md
@@ -1,8 +1,6 @@
-32-bit ABI bugs
-===============
+# 32-bit ABI bugs
 
-`off_t` is 32-bit
------------------
+## 32-bit `off_t` and `_FILE_OFFSET_BITS=64`
 
 On 32-bit Android, `off_t` is a signed 32-bit integer. This limits functions
 that use `off_t` to working on files no larger than 2GiB.
@@ -34,13 +32,35 @@
 increase your target API level, you'll have more and more of the functions
 available. API 12 adds some of the `<unistd.h>` functions, API 21 adds `mmap`,
 and by API 24 you have everything including `<stdio.h>`. See the
-[linker map](libc/libc.map.txt) for full details.
+[linker map](libc/libc.map.txt) for full details. Note also that in NDK r16 and
+later, if you're using Clang we'll inline an `mmap64` implementation in the
+headers when you target an API before 21 because it's an easy special case
+that's often needed. This means that code using `_FILE_OFFSET_BITS=64`
+and `mmap` (but no other functions that are unavailable at your target
+API level) will always compile.
+
+If your code stops compiling when you move to NDK r15 or later, removing every
+definition of `_FILE_OFFSET_BITS=64` will restore the behavior you used to have:
+you'll have a 32-bit `off_t` and use the 32-bit functions. Make sure you
+grep thoroughly in both your source and your build system: many people
+aren't aware that `_FILE_OFFSET_BITS` is set. You might also have to
+remove references to `__USE_FILE_OFFSET64` --- this is the internal
+flag that should never be set by user code but sometimes is (by zlib,
+for example). If you think you have removed these but your code still
+doesn't compile, you can insert this just before the line that's failing
+to double check:
+```
+#if _FILE_OFFSET_BITS == 64
+#error "oops, file _FILE_OFFSET_BITS == 64"
+#elif defined(__USE_FILE_OFFSET64)
+#error "oops, __USE_FILE_OFFSET64 is defined"
+#endif
+```
 
 In the 64-bit ABI, `off_t` is always 64-bit.
 
 
-`sigset_t` is too small for real-time signals
----------------------------------------------
+## `sigset_t` is too small for real-time signals
 
 On 32-bit Android, `sigset_t` is too small for ARM and x86 (but correct for
 MIPS). This means that there is no support for real-time signals in 32-bit
@@ -49,8 +69,7 @@
 In the 64-bit ABI, `sigset_t` is the correct size for every architecture.
 
 
-`time_t` is 32-bit
-------------------
+## `time_t` is 32-bit
 
 On 32-bit Android, `time_t` is 32-bit. The header `<time64.h>` and type
 `time64_t` exist as a workaround, but the kernel interfaces exposed on 32-bit
@@ -58,8 +77,7 @@
 
 In the 64-bit ABI, `time_t` is 64-bit.
 
-`pthread_mutex_t` is too small for large pids
----------------------------------------------
+## `pthread_mutex_t` is too small for large pids
 
 This doesn't generally affect Android devices, because on devices
 `/proc/sys/kernel/pid_max` is usually too small to hit the 16-bit limit,
diff --git a/libc/include/stdio.h b/libc/include/stdio.h
index 2d45fc5..e02a371 100644
--- a/libc/include/stdio.h
+++ b/libc/include/stdio.h
@@ -173,6 +173,7 @@
 int fseek(FILE* __fp, long __offset, int __whence);
 long ftell(FILE* __fp);
 
+/* See https://android.googlesource.com/platform/bionic/+/master/docs/32-bit-abi.md */
 #if defined(__USE_FILE_OFFSET64)
 int fgetpos(FILE* __fp, fpos_t* __pos) __RENAME(fgetpos64) __INTRODUCED_IN(24);
 int fsetpos(FILE* __fp, const fpos_t* __pos) __RENAME(fsetpos64) __INTRODUCED_IN(24);
diff --git a/libc/include/sys/cdefs.h b/libc/include/sys/cdefs.h
index 833ced0..3cf6723 100644
--- a/libc/include/sys/cdefs.h
+++ b/libc/include/sys/cdefs.h
@@ -205,25 +205,28 @@
  * In our header files we test against __USE_BSD and __USE_GNU.
  */
 #if defined(_GNU_SOURCE)
-# define __USE_BSD 1
-# define __USE_GNU 1
+#  define __USE_BSD 1
+#  define __USE_GNU 1
 #endif
 
 #if defined(_BSD_SOURCE)
-# define __USE_BSD 1
+#  define __USE_BSD 1
 #endif
 
-/* _FILE_OFFSET_BITS 64 support. */
+/*
+ * _FILE_OFFSET_BITS 64 support.
+ * See https://android.googlesource.com/platform/bionic/+/master/docs/32-bit-abi.md
+ */
 #if !defined(__LP64__) && defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS == 64
-#define __USE_FILE_OFFSET64 1
+#  define __USE_FILE_OFFSET64 1
 /*
  * Note that __RENAME_IF_FILE_OFFSET64 is only valid if the off_t and off64_t
  * functions were both added at the same API level because if you use this,
  * you only have one declaration to attach __INTRODUCED_IN to.
  */
-#define __RENAME_IF_FILE_OFFSET64(func) __RENAME(func)
+#  define __RENAME_IF_FILE_OFFSET64(func) __RENAME(func)
 #else
-#define __RENAME_IF_FILE_OFFSET64(func)
+#  define __RENAME_IF_FILE_OFFSET64(func)
 #endif
 
 /*
diff --git a/libc/include/sys/mman.h b/libc/include/sys/mman.h
index 028b024..5a7e3c0 100644
--- a/libc/include/sys/mman.h
+++ b/libc/include/sys/mman.h
@@ -44,8 +44,9 @@
 #define MREMAP_MAYMOVE  1
 #define MREMAP_FIXED    2
 
-#if defined(__USE_FILE_OFFSET64)
 /*
+ * See https://android.googlesource.com/platform/bionic/+/master/docs/32-bit-abi.md
+ *
  * mmap64 wasn't really around until L, but we added an inline for it since it
  * allows a lot more code to compile with _FILE_OFFSET_BITS=64.
  *
@@ -54,17 +55,18 @@
  * mmap64 to every translation unit that includes this header. Instead, just
  * preserve the old behavior for GCC and emit a useful diagnostic.
  */
+#if defined(__USE_FILE_OFFSET64)
 void* mmap(void* __addr, size_t __size, int __prot, int __flags, int __fd, off_t __offset)
-#if !defined(__clang__) && __ANDROID_API__ < __ANDROID_API_L__
-    __attribute__((error("mmap is not available with _FILE_OFFSET_BITS=64 when using GCC until "
-                         "android-21. Either raise your minSdkVersion, disable "
-                         "_FILE_OFFSET_BITS=64, or switch to Clang.")));
-#else
+#  if !defined(__clang__) && __ANDROID_API__ < __ANDROID_API_L__
+      __attribute__((error("mmap is not available with _FILE_OFFSET_BITS=64 when using GCC until "
+                           "android-21. Either raise your minSdkVersion, disable "
+                           "_FILE_OFFSET_BITS=64, or switch to Clang.")));
+#  else
     __RENAME(mmap64);
-#endif  /* defined(__clang__) */
+#  endif
 #else
 void* mmap(void* __addr, size_t __size, int __prot, int __flags, int __fd, off_t __offset);
-#endif  /* defined(__USE_FILE_OFFSET64) */
+#endif
 
 #if __ANDROID_API__ >= __ANDROID_API_L__
 void* mmap64(void* __addr, size_t __size, int __prot, int __flags, int __fd, off64_t __offset) __INTRODUCED_IN(21);
diff --git a/libc/include/sys/sendfile.h b/libc/include/sys/sendfile.h
index ecdb76c..97432c0 100644
--- a/libc/include/sys/sendfile.h
+++ b/libc/include/sys/sendfile.h
@@ -34,6 +34,7 @@
 
 __BEGIN_DECLS
 
+/* See https://android.googlesource.com/platform/bionic/+/master/docs/32-bit-abi.md */
 #if defined(__USE_FILE_OFFSET64)
 ssize_t sendfile(int __out_fd, int __in_fd, off_t* __offset, size_t __count) __RENAME(sendfile64) __INTRODUCED_IN(21);
 #else
diff --git a/libc/include/sys/types.h b/libc/include/sys/types.h
index 26ad6a5..f07c8fd 100644
--- a/libc/include/sys/types.h
+++ b/libc/include/sys/types.h
@@ -95,12 +95,13 @@
 typedef __kernel_time_t __time_t;
 typedef __time_t time_t;
 
+/* This historical accident means that we had a 32-bit off_t on 32-bit architectures. */
+/* See https://android.googlesource.com/platform/bionic/+/master/docs/32-bit-abi.md */
 #if defined(__USE_FILE_OFFSET64) || defined(__LP64__)
 typedef int64_t off_t;
 typedef off_t loff_t;
 typedef loff_t off64_t;
 #else
-/* This historical accident means that we had a 32-bit off_t on 32-bit architectures. */
 typedef __kernel_off_t off_t;
 typedef __kernel_loff_t loff_t;
 typedef loff_t off64_t;
diff --git a/libc/include/unistd.h b/libc/include/unistd.h
index c60cf80..ef75c84 100644
--- a/libc/include/unistd.h
+++ b/libc/include/unistd.h
@@ -168,16 +168,10 @@
 int fsync(int __fd);
 int fdatasync(int __fd) __INTRODUCED_IN(9);
 
-#if defined(__USE_FILE_OFFSET64)
-off_t lseek(int __fd, off_t __offset, int __whence) __RENAME(lseek64);
-#else
-off_t lseek(int __fd, off_t __offset, int __whence);
-#endif
-
-off64_t lseek64(int __fd, off64_t __offset, int __whence);
-
+/* See https://android.googlesource.com/platform/bionic/+/master/docs/32-bit-abi.md */
 #if defined(__USE_FILE_OFFSET64)
 int truncate(const char* __path, off_t __length) __RENAME(truncate64) __INTRODUCED_IN(21);
+off_t lseek(int __fd, off_t __offset, int __whence) __RENAME(lseek64);
 ssize_t pread(int __fd, void* __buf, size_t __count, off_t __offset)
   __overloadable __RENAME(pread64) __INTRODUCED_IN(12);
 ssize_t pwrite(int __fd, const void* __buf, size_t __count, off_t __offset)
@@ -185,6 +179,7 @@
 int ftruncate(int __fd, off_t __length) __RENAME(ftruncate64) __INTRODUCED_IN(12);
 #else
 int truncate(const char* __path, off_t __length);
+off_t lseek(int __fd, off_t __offset, int __whence);
 ssize_t pread(int __fd, void* __buf, size_t __count, off_t __offset)
     __overloadable __RENAME_CLANG(pread);
 ssize_t pwrite(int __fd, const void* __buf, size_t __count, off_t __offset)
@@ -193,6 +188,7 @@
 #endif
 
 int truncate64(const char* __path, off64_t __length) __INTRODUCED_IN(21);
+off64_t lseek64(int __fd, off64_t __offset, int __whence);
 ssize_t pread64(int __fd, void* __buf, size_t __count, off64_t __offset)
     __INTRODUCED_IN(12) __overloadable __RENAME_CLANG(pread64);
 ssize_t pwrite64(int __fd, const void* __buf, size_t __count, off64_t __offset)
diff --git a/tests/sys_ptrace_test.cpp b/tests/sys_ptrace_test.cpp
index d460dec..e6a1e22 100644
--- a/tests/sys_ptrace_test.cpp
+++ b/tests/sys_ptrace_test.cpp
@@ -271,18 +271,8 @@
 // test fail on arm64, you will likely need to cherry-pick fdfeff0f into your
 // kernel.
 TEST(sys_ptrace, watchpoint_imprecise) {
-  // Make sure we get interrupted in case a buggy kernel does not report the
-  // watchpoint hit correctly.
-  struct sigaction action, oldaction;
-  action.sa_handler = [](int) {};
-  sigemptyset(&action.sa_mask);
-  action.sa_flags = 0;
-  ASSERT_EQ(0, sigaction(SIGALRM, &action, &oldaction)) << strerror(errno);
-  alarm(5);
-
+  // This test relies on the infrastructure to timeout if the test hangs.
   run_watchpoint_test<Uint128_t>(watchpoint_imprecise_child, 8, sizeof(void*));
-
-  ASSERT_EQ(0, sigaction(SIGALRM, &oldaction, nullptr)) << strerror(errno);
 }
 
 static void __attribute__((noinline)) breakpoint_func() {
diff --git a/tests/time_test.cpp b/tests/time_test.cpp
index 9218078..e1fae92 100644
--- a/tests/time_test.cpp
+++ b/tests/time_test.cpp
@@ -654,31 +654,38 @@
   ASSERT_LT(t1 - t0, CLOCKS_PER_SEC / 1000);
 }
 
-pid_t GetInvalidPid() {
-  FILE* fp = fopen("/proc/sys/kernel/pid_max", "r");
+static pid_t GetInvalidPid() {
+  std::unique_ptr<FILE, decltype(&fclose)> fp{fopen("/proc/sys/kernel/pid_max", "r"), fclose};
   long pid_max;
-  fscanf(fp, "%ld", &pid_max);
-  pid_t invalid_pid = static_cast<pid_t>(pid_max + 1);
-  fclose(fp);
-  return invalid_pid;
+  fscanf(fp.get(), "%ld", &pid_max);
+  return static_cast<pid_t>(pid_max + 1);
 }
 
-TEST(time, clock_getcpuclockid) {
-  // For current process.
+TEST(time, clock_getcpuclockid_current) {
   clockid_t clockid;
   ASSERT_EQ(0, clock_getcpuclockid(getpid(), &clockid));
-
   timespec ts;
   ASSERT_EQ(0, clock_gettime(clockid, &ts));
+}
 
-  // For parent process.
+TEST(time, clock_getcpuclockid_parent) {
+  clockid_t clockid;
   ASSERT_EQ(0, clock_getcpuclockid(getppid(), &clockid));
+  timespec ts;
   ASSERT_EQ(0, clock_gettime(clockid, &ts));
+}
 
-  // For invalid process.
+TEST(time, clock_getcpuclockid_ESRCH) {
   // We can't use -1 for invalid pid here, because clock_getcpuclockid() can't detect it.
   errno = 0;
-  ASSERT_EQ(ESRCH, clock_getcpuclockid(GetInvalidPid(), &clockid));
+  // If this fails, your kernel needs commit e1b6b6ce to be backported.
+  clockid_t clockid;
+  ASSERT_EQ(ESRCH, clock_getcpuclockid(GetInvalidPid(), &clockid)) << "\n"
+    << "Please ensure that the following kernel patches or their replacements have been applied:\n"
+    << "* https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/"
+    << "commit/?id=e1b6b6ce55a0a25c8aa8af019095253b2133a41a\n"
+    << "* https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/"
+    << "commit/?id=c80ed088a519da53f27b798a69748eaabc66aadf\n";
   ASSERT_EQ(0, errno);
 }
 
diff --git a/tests/utils.h b/tests/utils.h
index 9a8eb5d..410b427 100644
--- a/tests/utils.h
+++ b/tests/utils.h
@@ -29,6 +29,7 @@
 #include <regex>
 
 #include <android-base/file.h>
+#include <android-base/macros.h>
 #include <android-base/scopeguard.h>
 #include <android-base/stringprintf.h>