From 6d07b68f5e95debebe3983f8b2d9bfbc2afbe970 Mon Sep 17 00:00:00 2001 From: Nikita Baksalyar Date: Wed, 27 Jan 2016 05:46:28 +0300 Subject: [PATCH] Fix problems with f64 and DirEntry on Illumos --- src/libstd/num/f64.rs | 92 ++++++++++++--------------------------- src/libstd/sys/unix/fs.rs | 12 +++-- 2 files changed, 37 insertions(+), 67 deletions(-) diff --git a/src/libstd/num/f64.rs b/src/libstd/num/f64.rs index f119b1d9f9a..ed047caa0a3 100644 --- a/src/libstd/num/f64.rs +++ b/src/libstd/num/f64.rs @@ -511,28 +511,7 @@ pub fn exp2(self) -> f64 { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn ln(self) -> f64 { - if !cfg!(target_os = "sunos") { - unsafe { intrinsics::logf64(self) } - } else { - // Illumos requires a wrapper around log, log2, and log10 functions - // because of their non-standard behavior (e.g. log(-n) returns -Inf instead - // of expected NaN). - if self.is_finite() { - if self > 0.0 { - unsafe { intrinsics::logf64(self) } - } else if self == 0.0 { - NEG_INFINITY // log(0) = -Inf - } else { - NAN // log(-n) = NaN - } - } else if self.is_nan() { - self // log(NaN) = NaN - } else if self > 0.0 { - self // log(Inf) = Inf - } else { - NAN // log(-Inf) = NaN - } - } + self.log_wrapper(|n| { unsafe { intrinsics::logf64(n) } }) } /// Returns the logarithm of the number with respect to an arbitrary base. @@ -567,27 +546,7 @@ pub fn log(self, base: f64) -> f64 { self.ln() / base.ln() } #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn log2(self) -> f64 { - if !cfg!(target_os = "sunos") { - unsafe { intrinsics::log2f64(self) } - } else { - // Illumos requires a wrapper around the log2 function because of - // its non-standard behavior - if self.is_finite() { - if self > 0.0 { - unsafe { intrinsics::log2f64(self) } - } else if self == 0.0 { - NEG_INFINITY // log2(0) = -Inf - } else { - NAN // log2(-n) = NaN - } - } else if self.is_nan() { - self // log2(NaN) = NaN - } else if self > 0.0 { - self // log2(Inf) = Inf - } else { - NAN // log2(-Inf) = NaN - } - } + self.log_wrapper(|n| { unsafe { intrinsics::log2f64(n) } }) } /// Returns the base 10 logarithm of the number. @@ -603,27 +562,7 @@ pub fn log2(self) -> f64 { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn log10(self) -> f64 { - if !cfg!(target_os = "sunos") { - unsafe { intrinsics::log10f64(self) } - } else { - // Illumos requires a wrapper around the log10 function because of - // its non-standard behavior. - if self.is_finite() { - if self > 0.0 { - unsafe { intrinsics::log10f64(self) } - } else if self == 0.0 { - NEG_INFINITY // log10(0) = -Inf - } else { - NAN // log10(-n) = NaN - } - } else if self.is_nan() { - self // log10(NaN) = NaN - } else if self > 0.0 { - self // log10(Inf) = Inf - } else { - NAN // log10(-Inf) = NaN - } - } + self.log_wrapper(|n| { unsafe { intrinsics::log10f64(n) } }) } /// Converts radians to degrees. @@ -1126,6 +1065,31 @@ pub fn acosh(self) -> f64 { pub fn atanh(self) -> f64 { 0.5 * ((2.0 * self) / (1.0 - self)).ln_1p() } + + // Illumos requires a wrapper around log, log2, and log10 functions + // because of their non-standard behavior (e.g. log(-n) returns -Inf instead + // of expected NaN). + fn log_wrapper f64>(self, log_fn: F) -> f64 { + if !cfg!(target_os = "sunos") { + log_fn(self) + } else { + if self.is_finite() { + if self > 0.0 { + log_fn(self) + } else if self == 0.0 { + NEG_INFINITY // log(0) = -Inf + } else { + NAN // log(-n) = NaN + } + } else if self.is_nan() { + self // log(NaN) = NaN + } else if self > 0.0 { + self // log(Inf) = Inf + } else { + NAN // log(-Inf) = NaN + } + } + } } #[cfg(test)] diff --git a/src/libstd/sys/unix/fs.rs b/src/libstd/sys/unix/fs.rs index 694aff6bbec..3e6242f6367 100644 --- a/src/libstd/sys/unix/fs.rs +++ b/src/libstd/sys/unix/fs.rs @@ -26,6 +26,8 @@ use vec::Vec; #[cfg(target_os = "sunos")] use core_collections::borrow::ToOwned; +#[cfg(target_os = "sunos")] +use boxed::Box; pub struct File(FileDesc); @@ -52,7 +54,7 @@ pub struct DirEntry { // store the name, b) its lifetime between readdir calls // is not guaranteed. #[cfg(target_os = "sunos")] - name: Arc> + name: Box<[u8]> } #[derive(Clone)] @@ -143,6 +145,10 @@ impl Iterator for ReadDir { fn next(&mut self) -> Option> { unsafe { loop { + // Although readdir_r(3) would be a correct function to use here because + // of the thread safety, on Illumos the readdir(3C) function is safe to use + // in threaded applications and it is generally preferred over the + // readdir_r(3C) function. let entry_ptr = libc::readdir(self.dirp.0); if entry_ptr.is_null() { return None @@ -153,8 +159,8 @@ fn next(&mut self) -> Option> { let ret = DirEntry { entry: *entry_ptr, - name: Arc::new(::slice::from_raw_parts(name as *const u8, - namelen as usize).to_owned()), + name: ::slice::from_raw_parts(name as *const u8, + namelen as usize).to_owned().into_boxed_slice(), root: self.root.clone() }; if ret.name_bytes() != b"." && ret.name_bytes() != b".." {