#[cfg(not(target_os = "nacl"))]
unsafe fn reset_sigpipe() {
- assert!(libc::signal(libc::SIGPIPE, libc::SIG_IGN) != !0);
+ assert!(signal(libc::SIGPIPE, libc::SIG_IGN) != !0);
}
#[cfg(target_os = "nacl")]
unsafe fn reset_sigpipe() {}
}
+// Currently the minimum supported Android version of the standard library is
+// API level 18 (android-18). Back in those days [1] the `signal` function was
+// just an inline wrapper around `bsd_signal`, but starting in API level
+// android-20 the `signal` symbols was introduced [2]. Finally, in android-21
+// the API `bsd_signal` was removed [3].
+//
+// Basically this means that if we want to be binary compatible with multiple
+// Android releases (oldest being 18 and newest being 21) then we need to check
+// for both symbols and not actually link against either.
+//
+// Note that if we're not on android we just link against the `android` symbol
+// itself.
+//
+// [1]: https://chromium.googlesource.com/android_tools/+/20ee6d20/ndk/platforms
+// /android-18/arch-arm/usr/include/signal.h
+// [2]: https://chromium.googlesource.com/android_tools/+/fbd420/ndk_experimental
+// /platforms/android-20/arch-arm
+// /usr/include/signal.h
+// [3]: https://chromium.googlesource.com/android_tools/+/20ee6d/ndk/platforms
+// /android-21/arch-arm/usr/include/signal.h
+#[cfg(target_os = "android")]
+unsafe fn signal(signum: libc::c_int,
+ handler: libc::sighandler_t) -> libc::sighandler_t {
+ weak!(fn signal(libc::c_int, libc::sighandler_t) -> libc::sighandler_t);
+ weak!(fn bsd_signal(libc::c_int, libc::sighandler_t) -> libc::sighandler_t);
+
+ let f = signal.get().or_else(|| bsd_signal.get());
+ let f = f.expect("neither `signal` nor `bsd_signal` symbols found");
+ f(signum, handler)
+}
+
+#[cfg(not(target_os = "android"))]
+pub use libc::signal;
+
pub fn decode_error_kind(errno: i32) -> ErrorKind {
match errno as libc::c_int {
libc::ECONNREFUSED => ErrorKind::ConnectionRefused,
t!(cvt(libc::sigemptyset(&mut set)));
t!(cvt(libc::pthread_sigmask(libc::SIG_SETMASK, &set,
ptr::null_mut())));
- let ret = libc::signal(libc::SIGPIPE, libc::SIG_DFL);
+ let ret = super::signal(libc::SIGPIPE, libc::SIG_DFL);
if ret == libc::SIG_ERR {
return io::Error::last_os_error()
}