diff options
Diffstat (limited to 'src/libstd/sys/unix')
| -rw-r--r-- | src/libstd/sys/unix/mod.rs | 36 | ||||
| -rw-r--r-- | src/libstd/sys/unix/os.rs | 12 | ||||
| -rw-r--r-- | src/libstd/sys/unix/process.rs | 2 | ||||
| -rw-r--r-- | src/libstd/sys/unix/time.rs | 7 | ||||
| -rw-r--r-- | src/libstd/sys/unix/weak.rs | 8 |
5 files changed, 54 insertions, 11 deletions
diff --git a/src/libstd/sys/unix/mod.rs b/src/libstd/sys/unix/mod.rs index c332d6035ee..f8b2d4dd232 100644 --- a/src/libstd/sys/unix/mod.rs +++ b/src/libstd/sys/unix/mod.rs @@ -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, diff --git a/src/libstd/sys/unix/os.rs b/src/libstd/sys/unix/os.rs index eed62c9ecfd..94ebbd70ae8 100644 --- a/src/libstd/sys/unix/os.rs +++ b/src/libstd/sys/unix/os.rs @@ -36,6 +36,7 @@ const TMPBUF_SZ: usize = 128; static ENV_LOCK: StaticMutex = StaticMutex::new(); /// Returns the platform-specific value of errno +#[cfg(not(target_os = "dragonfly"))] pub fn errno() -> i32 { extern { #[cfg_attr(any(target_os = "linux", target_os = "emscripten"), @@ -47,7 +48,6 @@ pub fn errno() -> i32 { target_env = "newlib"), link_name = "__errno")] #[cfg_attr(target_os = "solaris", link_name = "___errno")] - #[cfg_attr(target_os = "dragonfly", link_name = "__dfly_error")] #[cfg_attr(any(target_os = "macos", target_os = "ios", target_os = "freebsd"), @@ -60,6 +60,16 @@ pub fn errno() -> i32 { } } +#[cfg(target_os = "dragonfly")] +pub fn errno() -> i32 { + extern { + #[thread_local] + static errno: c_int; + } + + errno as i32 +} + /// Gets a detailed string description for the given error number. pub fn error_string(errno: i32) -> String { extern { diff --git a/src/libstd/sys/unix/process.rs b/src/libstd/sys/unix/process.rs index 6f56f3ade06..270c2096b2c 100644 --- a/src/libstd/sys/unix/process.rs +++ b/src/libstd/sys/unix/process.rs @@ -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() } diff --git a/src/libstd/sys/unix/time.rs b/src/libstd/sys/unix/time.rs index 1444cf31e85..cc7abe25e35 100644 --- a/src/libstd/sys/unix/time.rs +++ b/src/libstd/sys/unix/time.rs @@ -303,8 +303,13 @@ mod inner { } } + #[cfg(not(target_os = "dragonfly"))] + pub type clock_t = libc::c_int; + #[cfg(target_os = "dragonfly")] + pub type clock_t = libc::c_ulong; + impl Timespec { - pub fn now(clock: libc::c_int) -> Timespec { + pub fn now(clock: clock_t) -> Timespec { let mut t = Timespec { t: libc::timespec { tv_sec: 0, diff --git a/src/libstd/sys/unix/weak.rs b/src/libstd/sys/unix/weak.rs index e6f85c08d12..99ab8741159 100644 --- a/src/libstd/sys/unix/weak.rs +++ b/src/libstd/sys/unix/weak.rs @@ -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 } |
