diff --git a/ci/android-install-ndk.sh b/ci/android-install-ndk.sh
index 75bcd20f2f77d19a6253a94fbbf2657e359358eb..873f6c52c8f189c8de42edf4c0c3c3f406a7e394 100644
--- a/ci/android-install-ndk.sh
+++ b/ci/android-install-ndk.sh
@@ -11,8 +11,8 @@
 
 set -ex
 
-curl -O https://dl.google.com/android/repository/android-ndk-r13b-linux-x86_64.zip
-unzip -q android-ndk-r13b-linux-x86_64.zip
+curl -O https://dl.google.com/android/repository/android-ndk-r15b-linux-x86_64.zip
+unzip -q android-ndk-r15b-linux-x86_64.zip
 
 case "$1" in
   aarch64)
@@ -28,9 +28,10 @@ case "$1" in
     ;;
 esac;
 
-android-ndk-r13b/build/tools/make_standalone_toolchain.py \
+android-ndk-r15b/build/tools/make_standalone_toolchain.py \
+        --unified-headers \
         --install-dir /android/ndk-$1 \
         --arch $arch \
         --api 24
 
-rm -rf ./android-ndk-r13b-linux-x86_64.zip ./android-ndk-r13b
+rm -rf ./android-ndk-r15b-linux-x86_64.zip ./android-ndk-r15b
diff --git a/ci/docker/x86_64-linux-android/Dockerfile b/ci/docker/x86_64-linux-android/Dockerfile
index dfc0c83dae9237d57a93dac0e7036018ce1a4b15..0cfbc4820903a908227e4463efd404a32a61b682 100644
--- a/ci/docker/x86_64-linux-android/Dockerfile
+++ b/ci/docker/x86_64-linux-android/Dockerfile
@@ -17,7 +17,7 @@ RUN sh /android/android-install-ndk.sh $ANDROID_ARCH
 # We do not run x86_64-linux-android tests on an android emulator.
 # See ci/android-sysimage.sh for informations about how tests are run.
 COPY android-sysimage.sh /android/
-RUN bash /android/android-sysimage.sh x86_64 x86_64-21_r04.zip
+RUN bash /android/android-sysimage.sh x86_64 x86_64-24_r07.zip
 
 ENV PATH=$PATH:/rust/bin:/android/ndk-$ANDROID_ARCH/bin \
     CARGO_TARGET_X86_64_LINUX_ANDROID_LINKER=x86_64-linux-android-gcc \
diff --git a/ci/run-docker.sh b/ci/run-docker.sh
old mode 100644
new mode 100755
diff --git a/libc-test/build.rs b/libc-test/build.rs
index b77b3161b21913a562bdd9adcd85d6ce7f43ed79..6ff46b2c1610342a6a25f100a34fc0439c2fd6ac 100644
--- a/libc-test/build.rs
+++ b/libc-test/build.rs
@@ -179,7 +179,6 @@ fn main() {
         cfg.header("sys/shm.h");
         cfg.header("sys/user.h");
         cfg.header("sys/fsuid.h");
-        cfg.header("pty.h");
         cfg.header("shadow.h");
         cfg.header("linux/input.h");
         if x86_64 {
@@ -200,6 +199,7 @@ fn main() {
         cfg.header("sys/syscall.h");
         cfg.header("sys/personality.h");
         cfg.header("sys/swap.h");
+        cfg.header("pty.h");
         if !uclibc {
             cfg.header("sys/sysinfo.h");
         }
@@ -337,6 +337,11 @@ fn main() {
             // definition. Because it's tested on other Linux targets, skip it.
             "input_mask" if musl => true,
 
+            // These structs have changed since unified headers in NDK r14b.
+            // `st_atime` and `st_atime_nsec` have changed sign.
+            // FIXME: unskip it for next major release
+            "stat" | "stat64" if android => true,
+
             _ => false
         }
     });
@@ -534,6 +539,16 @@ fn main() {
             // On Mac we don't use the default `close()`, instead using their $NOCANCEL variants.
             "close" if apple => true,
 
+            // Definition of those functions as changed since unified headers from NDK r14b
+            // These changes imply some API breaking changes but are still ABI compatible.
+            // We can wait for the next major release to be compliant with the new API.
+            // FIXME: unskip these for next major release
+            "strerror_r" | "madvise" | "msync" | "mprotect" | "recvfrom" | "getpriority" |
+            "setpriority" | "personality" if android => true,
+            // In Android 64 bits, these functions have been fixed since unified headers.
+            // Ignore these until next major version.
+            "bind" | "writev" | "readv" | "sendmsg" | "recvmsg" if android && (aarch64 || x86_64) => true,
+
             _ => false,
         }
     });
diff --git a/src/unix/notbsd/android/b32/mod.rs b/src/unix/notbsd/android/b32/mod.rs
index 32f88e4987bacaa77c9f2a7466b7e83f9084b7f2..f6b0f03d48d12822796b11137a816a05ba3488c9 100644
--- a/src/unix/notbsd/android/b32/mod.rs
+++ b/src/unix/notbsd/android/b32/mod.rs
@@ -166,6 +166,9 @@ pub const UT_LINESIZE: usize = 8;
 pub const UT_NAMESIZE: usize = 8;
 pub const UT_HOSTSIZE: usize = 16;
 
+pub const SIGSTKSZ: ::size_t = 8192;
+pub const MINSIGSTKSZ: ::size_t = 2048;
+
 extern {
     pub fn bind(socket: ::c_int, address: *const ::sockaddr,
                 address_len: socklen_t) -> ::c_int;
diff --git a/src/unix/notbsd/android/b64/aarch64.rs b/src/unix/notbsd/android/b64/aarch64.rs
index 89c505d06f2e9fe6c2fd407755ad4949da237aad..5771340250bfdf39f7d7966203748f8d821c355f 100644
--- a/src/unix/notbsd/android/b64/aarch64.rs
+++ b/src/unix/notbsd/android/b64/aarch64.rs
@@ -54,3 +54,6 @@ pub const O_DIRECTORY: ::c_int = 0x4000;
 pub const O_NOFOLLOW: ::c_int = 0x8000;
 
 pub const SYS_gettid: ::c_long = 178;
+
+pub const SIGSTKSZ: ::size_t = 16384;
+pub const MINSIGSTKSZ: ::size_t = 5120;
diff --git a/src/unix/notbsd/android/b64/x86_64.rs b/src/unix/notbsd/android/b64/x86_64.rs
index 58d07e104dba40d2da2e847a272fe5c6e7916cec..7e824ccce8cec676bf2ed50f18b8f8b7cadc444f 100644
--- a/src/unix/notbsd/android/b64/x86_64.rs
+++ b/src/unix/notbsd/android/b64/x86_64.rs
@@ -48,3 +48,6 @@ pub const O_DIRECTORY: ::c_int = 0x10000;
 pub const O_NOFOLLOW: ::c_int = 0x20000;
 
 pub const SYS_gettid: ::c_long = 186;
+
+pub const SIGSTKSZ: ::size_t = 8192;
+pub const MINSIGSTKSZ: ::size_t = 2048;
diff --git a/src/unix/notbsd/android/mod.rs b/src/unix/notbsd/android/mod.rs
index d917647a9466866b5a340a78aab06d6412b8af55..95e0fa295bfeb478bc77b474a4acd68069fa1cab 100644
--- a/src/unix/notbsd/android/mod.rs
+++ b/src/unix/notbsd/android/mod.rs
@@ -173,6 +173,8 @@ pub const SA_NOCLDSTOP: ::c_int = 0x00000001;
 
 pub const EPOLL_CLOEXEC: ::c_int = 0x80000;
 pub const EPOLLONESHOT: ::c_int = 0x40000000;
+pub const EPOLLRDHUP: ::c_int = 0x00002000;
+pub const EPOLLWAKEUP: ::c_int = 0x20000000;
 
 pub const EFD_CLOEXEC: ::c_int = 0x80000;
 
@@ -428,7 +430,7 @@ pub const SOL_NETROM: ::c_int = 259;
 pub const SOL_ROSE: ::c_int = 260;
 
 #[doc(hidden)]
-pub const AF_MAX: ::c_int = 39;
+pub const AF_MAX: ::c_int = 43;
 #[doc(hidden)]
 pub const PF_MAX: ::c_int = AF_MAX;
 
@@ -458,6 +460,7 @@ pub const O_NONBLOCK: ::c_int = 2048;
 pub const O_SYNC: ::c_int = 0x101000;
 pub const O_ASYNC: ::c_int = 0x2000;
 pub const O_NDELAY: ::c_int = 0x800;
+pub const O_DSYNC: ::c_int = 4096;
 
 pub const NI_MAXHOST: ::size_t = 1025;
 
@@ -585,8 +588,6 @@ pub const LINUX_REBOOT_CMD_KEXEC: ::c_int = 0x45584543;
 pub const MCL_CURRENT: ::c_int = 0x0001;
 pub const MCL_FUTURE: ::c_int = 0x0002;
 
-pub const SIGSTKSZ: ::size_t = 8192;
-pub const MINSIGSTKSZ: ::size_t = 2048;
 pub const CBAUD: ::tcflag_t = 0o0010017;
 pub const TAB1: ::c_int = 0x00000800;
 pub const TAB2: ::c_int = 0x00001000;
diff --git a/src/unix/notbsd/linux/mips/mod.rs b/src/unix/notbsd/linux/mips/mod.rs
index b2ad107caedf983d0acf041d24ef96b456e7c755..0354c1e13b778033d48695cc764d339b3796215b 100644
--- a/src/unix/notbsd/linux/mips/mod.rs
+++ b/src/unix/notbsd/linux/mips/mod.rs
@@ -27,8 +27,6 @@ s! {
     }
 }
 
-pub const CLONE_NEWCGROUP: ::c_int = 0x02000000;
-
 pub const SFD_CLOEXEC: ::c_int = 0x080000;
 
 pub const NCCS: usize = 32;
diff --git a/src/unix/notbsd/linux/mod.rs b/src/unix/notbsd/linux/mod.rs
index 40dd63f255b696517622810995b90dddfa4aaebe..670402e723c8254a8cbcd40181f635d8eda947b0 100644
--- a/src/unix/notbsd/linux/mod.rs
+++ b/src/unix/notbsd/linux/mod.rs
@@ -1013,7 +1013,6 @@ extern {
                        timeout: ::c_int,
                        sigmask: *const ::sigset_t) -> ::c_int;
     pub fn dup3(oldfd: ::c_int, newfd: ::c_int, flags: ::c_int) -> ::c_int;
-    pub fn sethostname(name: *const ::c_char, len: ::size_t) -> ::c_int;
     pub fn mkostemp(template: *mut ::c_char, flags: ::c_int) -> ::c_int;
     pub fn mkostemps(template: *mut ::c_char,
                      suffixlen: ::c_int,
@@ -1023,15 +1022,6 @@ extern {
                         timeout: *const ::timespec) -> ::c_int;
     pub fn sigwaitinfo(set: *const sigset_t,
                        info: *mut siginfo_t) -> ::c_int;
-    pub fn openpty(amaster: *mut ::c_int,
-                   aslave: *mut ::c_int,
-                   name: *mut ::c_char,
-                   termp: *const termios,
-                   winp: *const ::winsize) -> ::c_int;
-    pub fn forkpty(amaster: *mut ::c_int,
-                   name: *mut ::c_char,
-                   termp: *const termios,
-                   winp: *const ::winsize) -> ::pid_t;
     pub fn nl_langinfo_l(item: ::nl_item, locale: ::locale_t) -> *mut ::c_char;
     pub fn getnameinfo(sa: *const ::sockaddr,
                        salen: ::socklen_t,
@@ -1064,8 +1054,6 @@ extern {
     pub fn reboot(how_to: ::c_int) -> ::c_int;
     pub fn setfsgid(gid: ::gid_t) -> ::c_int;
     pub fn setfsuid(uid: ::uid_t) -> ::c_int;
-    pub fn setresgid(rgid: ::gid_t, egid: ::gid_t, sgid: ::gid_t) -> ::c_int;
-    pub fn setresuid(ruid: ::uid_t, euid: ::uid_t, suid: ::uid_t) -> ::c_int;
 
     // Not available now on Android
     pub fn mkfifoat(dirfd: ::c_int, pathname: *const ::c_char,
diff --git a/src/unix/notbsd/linux/musl/mod.rs b/src/unix/notbsd/linux/musl/mod.rs
index b365028b76aca6443ad3656bdffebb1a4bf8485a..fd0317cde8c5218bcf30cbcba318c03678929c82 100644
--- a/src/unix/notbsd/linux/musl/mod.rs
+++ b/src/unix/notbsd/linux/musl/mod.rs
@@ -87,8 +87,6 @@ s! {
     }
 }
 
-pub const CLONE_NEWCGROUP: ::c_int = 0x02000000;
-
 pub const SFD_CLOEXEC: ::c_int = 0x080000;
 
 pub const NCCS: usize = 32;
diff --git a/src/unix/notbsd/linux/other/b32/mod.rs b/src/unix/notbsd/linux/other/b32/mod.rs
index 8b8b1d5ac2fd5843f7b8f0ef606c63ba1b3e07b6..12852b76064545dda5f9475b2b0f67143e2d1feb 100644
--- a/src/unix/notbsd/linux/other/b32/mod.rs
+++ b/src/unix/notbsd/linux/other/b32/mod.rs
@@ -225,7 +225,6 @@ pub const TIOCMBIS: ::c_ulong = 0x5416;
 pub const TIOCMBIC: ::c_ulong = 0x5417;
 pub const TIOCMSET: ::c_ulong = 0x5418;
 pub const TIOCCONS: ::c_ulong = 0x541D;
-pub const CLONE_NEWCGROUP: ::c_int = 0x02000000;
 
 pub const SFD_CLOEXEC: ::c_int = 0x080000;
 
diff --git a/src/unix/notbsd/linux/other/b64/aarch64.rs b/src/unix/notbsd/linux/other/b64/aarch64.rs
index 705ae52fba4319c5c7169f4af75a8c0ad38097d5..83439609f320ee3a3a4d65e1b318858626c2388d 100644
--- a/src/unix/notbsd/linux/other/b64/aarch64.rs
+++ b/src/unix/notbsd/linux/other/b64/aarch64.rs
@@ -288,8 +288,6 @@ pub const TIOCMBIC: ::c_ulong = 0x5417;
 pub const TIOCMSET: ::c_ulong = 0x5418;
 pub const TIOCCONS: ::c_ulong = 0x541D;
 
-pub const CLONE_NEWCGROUP: ::c_int = 0x02000000;
-
 pub const SFD_CLOEXEC: ::c_int = 0x080000;
 
 pub const NCCS: usize = 32;
diff --git a/src/unix/notbsd/linux/other/b64/powerpc64.rs b/src/unix/notbsd/linux/other/b64/powerpc64.rs
index 7ff498d5f2b560a8ef594291c9067125c7664933..192b722e1a8bcf252e180aeceb5e8faecca85c6a 100644
--- a/src/unix/notbsd/linux/other/b64/powerpc64.rs
+++ b/src/unix/notbsd/linux/other/b64/powerpc64.rs
@@ -286,8 +286,6 @@ pub const TIOCMBIC: ::c_ulong = 0x5417;
 pub const TIOCMSET: ::c_ulong = 0x5418;
 pub const TIOCCONS: ::c_ulong = 0x541D;
 
-pub const CLONE_NEWCGROUP: ::c_int = 0x02000000;
-
 pub const SFD_CLOEXEC: ::c_int = 0x080000;
 
 pub const NCCS: usize = 32;
diff --git a/src/unix/notbsd/linux/other/b64/x86_64.rs b/src/unix/notbsd/linux/other/b64/x86_64.rs
index b5bddb6209642fd81a03180a52b345b3c5e776d4..a14924bede2ef8c114ae45d214e1e8eaad1bcae1 100644
--- a/src/unix/notbsd/linux/other/b64/x86_64.rs
+++ b/src/unix/notbsd/linux/other/b64/x86_64.rs
@@ -389,8 +389,6 @@ pub const TIOCMBIC: ::c_ulong = 0x5417;
 pub const TIOCMSET: ::c_ulong = 0x5418;
 pub const TIOCCONS: ::c_ulong = 0x541D;
 
-pub const CLONE_NEWCGROUP: ::c_int = 0x02000000;
-
 pub const SFD_CLOEXEC: ::c_int = 0x080000;
 
 pub const NCCS: usize = 32;
diff --git a/src/unix/notbsd/linux/s390x.rs b/src/unix/notbsd/linux/s390x.rs
index 1c0cd56d6f14c08ccd5ffd7fd3000024dc84abb2..4c893d5ac50429a8100e9b5433afe803c393108e 100644
--- a/src/unix/notbsd/linux/s390x.rs
+++ b/src/unix/notbsd/linux/s390x.rs
@@ -273,8 +273,6 @@ s! {
     }
 }
 
-pub const CLONE_NEWCGROUP: ::c_int = 0x02000000;
-
 pub const SFD_CLOEXEC: ::c_int = 0x080000;
 
 pub const NCCS: usize = 32;
diff --git a/src/unix/notbsd/mod.rs b/src/unix/notbsd/mod.rs
index e10d28b304d7036febb382bd0053579d4b450cbe..7df3c845918c43c45aae0e33332fee1248f95772 100644
--- a/src/unix/notbsd/mod.rs
+++ b/src/unix/notbsd/mod.rs
@@ -703,6 +703,7 @@ pub const CLONE_NEWUSER: ::c_int = 0x10000000;
 pub const CLONE_NEWPID: ::c_int = 0x20000000;
 pub const CLONE_NEWNET: ::c_int = 0x40000000;
 pub const CLONE_IO: ::c_int = 0x80000000;
+pub const CLONE_NEWCGROUP: ::c_int = 0x02000000;
 
 pub const WNOHANG: ::c_int = 0x00000001;
 pub const WUNTRACED: ::c_int = 0x00000002;
@@ -1007,8 +1008,20 @@ extern {
     pub fn brk(addr: *mut ::c_void) -> ::c_int;
     pub fn sbrk(increment: ::intptr_t) -> *mut ::c_void;
     pub fn vfork() -> ::pid_t;
+    pub fn sethostname(name: *const ::c_char, len: ::size_t) -> ::c_int;
+    pub fn setresgid(rgid: ::gid_t, egid: ::gid_t, sgid: ::gid_t) -> ::c_int;
+    pub fn setresuid(ruid: ::uid_t, euid: ::uid_t, suid: ::uid_t) -> ::c_int;
     pub fn wait4(pid: ::pid_t, status: *mut ::c_int, options: ::c_int,
                  rusage: *mut ::rusage) -> ::pid_t;
+    pub fn openpty(amaster: *mut ::c_int,
+                aslave: *mut ::c_int,
+                name: *mut ::c_char,
+                termp: *const termios,
+                winp: *const ::winsize) -> ::c_int;
+    pub fn forkpty(amaster: *mut ::c_int,
+                name: *mut ::c_char,
+                termp: *const termios,
+                winp: *const ::winsize) -> ::pid_t;
 }
 
 cfg_if! {