diff options
Diffstat (limited to 'src/libstd/sys')
| -rw-r--r-- | src/libstd/sys/common/args.rs | 3 | ||||
| -rw-r--r-- | src/libstd/sys/common/libunwind.rs | 1 | ||||
| -rw-r--r-- | src/libstd/sys/unix/fd.rs | 4 | ||||
| -rw-r--r-- | src/libstd/sys/unix/fs.rs | 56 | ||||
| -rw-r--r-- | src/libstd/sys/unix/mod.rs | 1 | ||||
| -rw-r--r-- | src/libstd/sys/unix/os.rs | 64 | ||||
| -rw-r--r-- | src/libstd/sys/unix/process.rs | 2 | ||||
| -rw-r--r-- | src/libstd/sys/unix/stack_overflow.rs | 2 | ||||
| -rw-r--r-- | src/libstd/sys/unix/thread.rs | 24 | 
9 files changed, 132 insertions, 25 deletions
diff --git a/src/libstd/sys/common/args.rs b/src/libstd/sys/common/args.rs index 4cfddb036e9..4600983eb3b 100644 --- a/src/libstd/sys/common/args.rs +++ b/src/libstd/sys/common/args.rs @@ -38,7 +38,8 @@ pub fn clone() -> Option<Vec<Vec<u8>>> { imp::clone() } target_os = "dragonfly", target_os = "bitrig", target_os = "netbsd", - target_os = "openbsd"))] + target_os = "openbsd", + target_os = "solaris"))] mod imp { use prelude::v1::*; diff --git a/src/libstd/sys/common/libunwind.rs b/src/libstd/sys/common/libunwind.rs index f44a8cb21e9..956f6005f1c 100644 --- a/src/libstd/sys/common/libunwind.rs +++ b/src/libstd/sys/common/libunwind.rs @@ -101,6 +101,7 @@ pub type _Unwind_Exception_Cleanup_Fn = #[cfg_attr(any(all(target_os = "linux", not(target_env = "musl")), target_os = "freebsd", + target_os = "solaris", all(target_os = "linux", target_env = "musl", not(target_arch = "x86_64"))), link(name = "gcc_s"))] #[cfg_attr(all(target_os = "linux", target_env = "musl", target_arch = "x86_64", not(test)), diff --git a/src/libstd/sys/unix/fd.rs b/src/libstd/sys/unix/fd.rs index e09f4ca27bc..94775341c38 100644 --- a/src/libstd/sys/unix/fd.rs +++ b/src/libstd/sys/unix/fd.rs @@ -50,14 +50,14 @@ impl FileDesc { Ok(ret as usize) } - #[cfg(not(target_env = "newlib"))] + #[cfg(not(any(target_env = "newlib", target_os = "solaris")))] pub fn set_cloexec(&self) { unsafe { let ret = libc::ioctl(self.fd, libc::FIOCLEX); debug_assert_eq!(ret, 0); } } - #[cfg(target_env = "newlib")] + #[cfg(any(target_env = "newlib", target_os = "solaris"))] pub fn set_cloexec(&self) { unsafe { let previous = libc::fcntl(self.fd, libc::F_GETFD); diff --git a/src/libstd/sys/unix/fs.rs b/src/libstd/sys/unix/fs.rs index 91931811234..f5d03cad657 100644 --- a/src/libstd/sys/unix/fs.rs +++ b/src/libstd/sys/unix/fs.rs @@ -8,14 +8,14 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use prelude::v1::*; use io::prelude::*; use os::unix::prelude::*; use ffi::{CString, CStr, OsString, OsStr}; use fmt; use io::{self, Error, ErrorKind, SeekFrom}; -use libc::{dirent, readdir_r}; -use libc::{self, c_int, off_t, mode_t}; +use libc::{self, dirent, c_int, off_t, mode_t}; use mem; use path::{Path, PathBuf}; use ptr; @@ -24,7 +24,6 @@ use sys::fd::FileDesc; use sys::platform::raw; use sys::{cvt, cvt_r}; use sys_common::{AsInner, FromInner}; -use vec::Vec; pub struct File(FileDesc); @@ -46,6 +45,12 @@ unsafe impl Sync for Dir {} pub struct DirEntry { entry: dirent, root: Arc<PathBuf>, + // We need to store an owned copy of the directory name + // on Solaris because a) it uses a zero-length array to + // store the name, b) its lifetime between readdir calls + // is not guaranteed. + #[cfg(target_os = "solaris")] + name: Box<[u8]> } #[derive(Clone)] @@ -132,6 +137,36 @@ impl FromInner<raw::mode_t> for FilePermissions { impl Iterator for ReadDir { type Item = io::Result<DirEntry>; + #[cfg(target_os = "solaris")] + fn next(&mut self) -> Option<io::Result<DirEntry>> { + 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 + } + + let name = (*entry_ptr).d_name.as_ptr(); + let namelen = libc::strlen(name) as usize; + + let ret = DirEntry { + entry: *entry_ptr, + 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".." { + return Some(Ok(ret)) + } + } + } + } + + #[cfg(not(target_os = "solaris"))] fn next(&mut self) -> Option<io::Result<DirEntry>> { unsafe { let mut ret = DirEntry { @@ -140,7 +175,7 @@ impl Iterator for ReadDir { }; let mut entry_ptr = ptr::null_mut(); loop { - if readdir_r(self.dirp.0, &mut ret.entry, &mut entry_ptr) != 0 { + if libc::readdir_r(self.dirp.0, &mut ret.entry, &mut entry_ptr) != 0 { return Some(Err(Error::last_os_error())) } if entry_ptr.is_null() { @@ -174,6 +209,12 @@ impl DirEntry { lstat(&self.path()) } + #[cfg(target_os = "solaris")] + pub fn file_type(&self) -> io::Result<FileType> { + stat(&self.path()).map(|m| m.file_type()) + } + + #[cfg(not(target_os = "solaris"))] pub fn file_type(&self) -> io::Result<FileType> { match self.entry.d_type { libc::DT_CHR => Ok(FileType { mode: libc::S_IFCHR }), @@ -189,7 +230,8 @@ impl DirEntry { #[cfg(any(target_os = "macos", target_os = "ios", - target_os = "linux"))] + target_os = "linux", + target_os = "solaris"))] pub fn ino(&self) -> raw::ino_t { self.entry.d_ino } @@ -228,6 +270,10 @@ impl DirEntry { CStr::from_ptr(self.entry.d_name.as_ptr()).to_bytes() } } + #[cfg(target_os = "solaris")] + fn name_bytes(&self) -> &[u8] { + &*self.name + } } impl OpenOptions { diff --git a/src/libstd/sys/unix/mod.rs b/src/libstd/sys/unix/mod.rs index 2e89becfa67..f8a4bcdecd7 100644 --- a/src/libstd/sys/unix/mod.rs +++ b/src/libstd/sys/unix/mod.rs @@ -25,6 +25,7 @@ use ops::Neg; #[cfg(target_os = "nacl")] pub use os::nacl as platform; #[cfg(target_os = "netbsd")] pub use os::netbsd as platform; #[cfg(target_os = "openbsd")] pub use os::openbsd as platform; +#[cfg(target_os = "solaris")] pub use os::solaris as platform; pub mod backtrace; pub mod condvar; diff --git a/src/libstd/sys/unix/os.rs b/src/libstd/sys/unix/os.rs index c62960d74cb..da770514593 100644 --- a/src/libstd/sys/unix/os.rs +++ b/src/libstd/sys/unix/os.rs @@ -45,6 +45,7 @@ pub fn errno() -> i32 { target_os = "android", 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", @@ -257,6 +258,30 @@ pub fn current_exe() -> io::Result<PathBuf> { } } +#[cfg(any(target_os = "solaris"))] +pub fn current_exe() -> io::Result<PathBuf> { + extern { + fn getexecname() -> *const c_char; + } + unsafe { + let path = getexecname(); + if path.is_null() { + Err(io::Error::last_os_error()) + } else { + let filename = CStr::from_ptr(path).to_bytes(); + let path = PathBuf::from(<OsStr as OsStrExt>::from_bytes(filename)); + + // Prepend a current working directory to the path if + // it doesn't contain an absolute pathname. + if filename[0] == b'/' { + Ok(path) + } else { + getcwd().map(|cwd| cwd.join(path)) + } + } + } +} + pub struct Args { iter: vec::IntoIter<OsString>, _dont_send_or_sync_me: *mut (), @@ -359,6 +384,7 @@ pub fn args() -> Args { target_os = "bitrig", target_os = "netbsd", target_os = "openbsd", + target_os = "solaris", target_os = "nacl"))] pub fn args() -> Args { use sys_common; @@ -489,6 +515,28 @@ pub fn home_dir() -> Option<PathBuf> { target_os = "ios", target_os = "nacl")))] unsafe fn fallback() -> Option<OsString> { + #[cfg(not(target_os = "solaris"))] + unsafe fn getpwduid_r(me: libc::uid_t, passwd: &mut libc::passwd, + buf: &mut Vec<c_char>) -> Option<()> { + let mut result = ptr::null_mut(); + match libc::getpwuid_r(me, passwd, buf.as_mut_ptr(), + buf.capacity() as libc::size_t, + &mut result) { + 0 if !result.is_null() => Some(()), + _ => None + } + } + + #[cfg(target_os = "solaris")] + unsafe fn getpwduid_r(me: libc::uid_t, passwd: &mut libc::passwd, + buf: &mut Vec<c_char>) -> Option<()> { + // getpwuid_r semantics is different on Illumos/Solaris: + // http://illumos.org/man/3c/getpwuid_r + let result = libc::getpwuid_r(me, passwd, buf.as_mut_ptr(), + buf.capacity() as libc::size_t); + if result.is_null() { None } else { Some(()) } + } + let amt = match libc::sysconf(libc::_SC_GETPW_R_SIZE_MAX) { n if n < 0 => 512 as usize, n => n as usize, @@ -497,16 +545,14 @@ pub fn home_dir() -> Option<PathBuf> { loop { let mut buf = Vec::with_capacity(amt); let mut passwd: libc::passwd = mem::zeroed(); - let mut result = ptr::null_mut(); - match libc::getpwuid_r(me, &mut passwd, buf.as_mut_ptr(), - buf.capacity() as libc::size_t, - &mut result) { - 0 if !result.is_null() => {} - _ => return None + + if getpwduid_r(me, &mut passwd, &mut buf).is_some() { + let ptr = passwd.pw_dir as *const _; + let bytes = CStr::from_ptr(ptr).to_bytes().to_vec(); + return Some(OsStringExt::from_vec(bytes)) + } else { + return None; } - let ptr = passwd.pw_dir as *const _; - let bytes = CStr::from_ptr(ptr).to_bytes().to_vec(); - return Some(OsStringExt::from_vec(bytes)) } } } diff --git a/src/libstd/sys/unix/process.rs b/src/libstd/sys/unix/process.rs index 04b39f0851a..3ce2c684f07 100644 --- a/src/libstd/sys/unix/process.rs +++ b/src/libstd/sys/unix/process.rs @@ -131,7 +131,7 @@ impl fmt::Debug for Command { pub struct ExitStatus(c_int); #[cfg(any(target_os = "linux", target_os = "android", - target_os = "nacl"))] + target_os = "nacl", target_os = "solaris"))] mod status_imp { pub fn WIFEXITED(status: i32) -> bool { (status & 0xff) == 0 } pub fn WEXITSTATUS(status: i32) -> i32 { (status >> 8) & 0xff } diff --git a/src/libstd/sys/unix/stack_overflow.rs b/src/libstd/sys/unix/stack_overflow.rs index b5cbcaa44d5..84407b3bee8 100644 --- a/src/libstd/sys/unix/stack_overflow.rs +++ b/src/libstd/sys/unix/stack_overflow.rs @@ -39,6 +39,7 @@ impl Drop for Handler { target_os = "bitrig", target_os = "dragonfly", target_os = "freebsd", + target_os = "solaris", all(target_os = "netbsd", not(target_vendor = "rumprun")), target_os = "openbsd"))] mod imp { @@ -179,6 +180,7 @@ mod imp { target_os = "bitrig", target_os = "dragonfly", target_os = "freebsd", + target_os = "solaris", all(target_os = "netbsd", not(target_vendor = "rumprun")), target_os = "openbsd")))] mod imp { diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs index 0faa1465c32..277aa5f19f0 100644 --- a/src/libstd/sys/unix/thread.rs +++ b/src/libstd/sys/unix/thread.rs @@ -12,7 +12,7 @@ use prelude::v1::*; use alloc::boxed::FnBox; use cmp; -#[cfg(not(target_env = "newlib"))] +#[cfg(not(any(target_env = "newlib", target_os = "solaris")))] use ffi::CString; use io; use libc; @@ -122,9 +122,9 @@ impl Thread { carg.as_ptr() as *mut libc::c_void); } } - #[cfg(target_env = "newlib")] - pub unsafe fn set_name(_name: &str) { - // Newlib has no way to set a thread name. + #[cfg(any(target_env = "newlib", target_os = "solaris"))] + pub fn set_name(_name: &str) { + // Newlib and Illumos has no way to set a thread name. } pub fn sleep(dur: Duration) { @@ -170,7 +170,8 @@ impl Drop for Thread { not(target_os = "macos"), not(target_os = "bitrig"), not(all(target_os = "netbsd", not(target_vendor = "rumprun"))), - not(target_os = "openbsd")))] + not(target_os = "openbsd"), + not(target_os = "solaris")))] #[cfg_attr(test, allow(dead_code))] pub mod guard { pub unsafe fn current() -> Option<usize> { None } @@ -182,7 +183,8 @@ pub mod guard { target_os = "macos", target_os = "bitrig", all(target_os = "netbsd", not(target_vendor = "rumprun")), - target_os = "openbsd"))] + target_os = "openbsd", + target_os = "solaris"))] #[cfg_attr(test, allow(dead_code))] pub mod guard { use prelude::v1::*; @@ -194,7 +196,8 @@ pub mod guard { #[cfg(any(target_os = "macos", target_os = "bitrig", - target_os = "openbsd"))] + target_os = "openbsd", + target_os = "solaris"))] unsafe fn get_stack_start() -> Option<*mut libc::c_void> { current().map(|s| s as *mut libc::c_void) } @@ -253,6 +256,13 @@ pub mod guard { Some(stackaddr as usize + offset * psize) } + #[cfg(target_os = "solaris")] + pub unsafe fn current() -> Option<usize> { + let mut current_stack: libc::stack_t = ::mem::zeroed(); + assert_eq!(libc::stack_getbounds(&mut current_stack), 0); + Some(current_stack.ss_sp as usize) + } + #[cfg(target_os = "macos")] pub unsafe fn current() -> Option<usize> { Some((libc::pthread_get_stackaddr_np(libc::pthread_self()) as libc::size_t -  | 
