Skip to content

Commit

Permalink
std: Fix linking against signal on Android
Browse files Browse the repository at this point in the history
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.

This was first discovered in rust-lang/libc#236 with a fix proposed in
rust-lang/libc#237. I suspect that we'll want to accept rust-lang/libc#237 so
Rust crates at large continue to be compatible with newer releases of Android
and crates, like the standard library, that want to opt into older support can
continue to do so via similar means.

Closes rust-lang/libc#236

[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
  • Loading branch information
alexcrichton committed Apr 5, 2016
1 parent 3ec71b0 commit 9c462b8
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 10 deletions.
2 changes: 1 addition & 1 deletion src/liblibc
Submodule liblibc updated 45 files
+1 −3 .travis.yml
+1 −1 Cargo.toml
+0 −4 appveyor.yml
+3 −7 ci/landing-page-footer.html
+7 −4 ci/landing-page-head.html
+12 −25 libc-test/Cargo.lock
+10 −0 libc-test/build.rs
+5 −5 libc-test/generate-files/Cargo.lock
+3 −1 src/lib.rs
+3 −0 src/unix/bsd/apple/b32.rs
+3 −0 src/unix/bsd/apple/b64.rs
+101 −1 src/unix/bsd/apple/mod.rs
+18 −1 src/unix/bsd/freebsdlike/dragonfly/mod.rs
+19 −2 src/unix/bsd/freebsdlike/freebsd/mod.rs
+46 −4 src/unix/bsd/freebsdlike/mod.rs
+10 −1 src/unix/bsd/mod.rs
+27 −0 src/unix/bsd/openbsdlike/bitrig.rs
+27 −4 src/unix/bsd/openbsdlike/mod.rs
+27 −0 src/unix/bsd/openbsdlike/netbsd.rs
+27 −0 src/unix/bsd/openbsdlike/openbsd.rs
+17 −4 src/unix/mod.rs
+9 −1 src/unix/notbsd/android/mod.rs
+7 −0 src/unix/notbsd/linux/mips.rs
+10 −21 src/unix/notbsd/linux/mod.rs
+1 −0 src/unix/notbsd/linux/musl/b32/arm.rs
+1 −0 src/unix/notbsd/linux/musl/b32/mips.rs
+3 −1 src/unix/notbsd/linux/musl/b32/mod.rs
+1 −0 src/unix/notbsd/linux/musl/b32/x86.rs
+1 −0 src/unix/notbsd/linux/musl/b64/aarch64.rs
+14 −1 src/unix/notbsd/linux/musl/b64/mod.rs
+1 −0 src/unix/notbsd/linux/musl/b64/powerpc64.rs
+3 −0 src/unix/notbsd/linux/musl/b64/x86_64.rs
+5 −0 src/unix/notbsd/linux/musl/mod.rs
+1 −0 src/unix/notbsd/linux/other/b32/arm.rs
+1 −1 src/unix/notbsd/linux/other/b32/mod.rs
+1 −0 src/unix/notbsd/linux/other/b32/powerpc.rs
+1 −0 src/unix/notbsd/linux/other/b32/x86.rs
+1 −0 src/unix/notbsd/linux/other/b64/aarch64.rs
+3 −1 src/unix/notbsd/linux/other/b64/mod.rs
+1 −0 src/unix/notbsd/linux/other/b64/powerpc64.rs
+1 −0 src/unix/notbsd/linux/other/b64/x86_64.rs
+8 −1 src/unix/notbsd/linux/other/mod.rs
+84 −4 src/unix/notbsd/mod.rs
+15 −3 src/unix/solaris/mod.rs
+3 −1 src/windows.rs
36 changes: 35 additions & 1 deletion src/libstd/sys/unix/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,12 +85,46 @@ pub fn init() {

#[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,
Expand Down
2 changes: 1 addition & 1 deletion src/libstd/sys/unix/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ impl Command {
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()
}
Expand Down
8 changes: 1 addition & 7 deletions src/libstd/sys/unix/weak.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,5 @@ unsafe fn fetch(name: &str) -> usize {
Ok(cstr) => cstr,
Err(..) => return 0,
};
let lib = libc::dlopen(0 as *const _, libc::RTLD_LAZY);
if lib.is_null() {
return 0
}
let ret = libc::dlsym(lib, name.as_ptr()) as usize;
libc::dlclose(lib);
return ret
libc::dlsym(libc::RTLD_DEFAULT, name.as_ptr()) as usize
}

0 comments on commit 9c462b8

Please sign in to comment.