diff --git a/configure b/configure index 9576e36828a32..27e0234a7dee3 100755 --- a/configure +++ b/configure @@ -1,5 +1,13 @@ #!/bin/sh +# /bin/sh on Solaris is not a POSIX compatible shell, but /usr/bin/bash is. +if [ `uname -s` = 'SunOS' -a "${POSIX_SHELL}" != "true" ]; then + POSIX_SHELL="true" + export POSIX_SHELL + exec /usr/bin/env bash $0 "$@" +fi +unset POSIX_SHELL # clear it so if we invoke other scripts, they run as bash as well + msg() { echo "configure: $*" } @@ -416,6 +424,11 @@ case $CFG_OSTYPE in CFG_OSTYPE=apple-darwin ;; + SunOS) + CFG_OSTYPE=sun-solaris + CFG_CPUTYPE=$(isainfo -n) + ;; + MINGW*) # msys' `uname` does not print gcc configuration, but prints msys # configuration. so we cannot believe `uname -m`: diff --git a/mk/cfg/x86_64-sun-solaris.mk b/mk/cfg/x86_64-sun-solaris.mk new file mode 100644 index 0000000000000..0a09a5cf72d9f --- /dev/null +++ b/mk/cfg/x86_64-sun-solaris.mk @@ -0,0 +1,23 @@ +# x86_64-sun-solaris configuration +CROSS_PREFIX_x86_64-sun-solaris=x86_64-sun-solaris2.11- +CC_x86_64-sun-solaris=$(CC) +CXX_x86_64-sun-solaris=$(CXX) +CPP_x86_64-sun-solaris=$(CPP) +AR_x86_64-sun-solaris=$(AR) +CFG_LIB_NAME_x86_64-sun-solaris=lib$(1).so +CFG_STATIC_LIB_NAME_x86_64-sun-solaris=lib$(1).a +CFG_LIB_GLOB_x86_64-sun-solaris=lib$(1)-*.so +CFG_LIB_DSYM_GLOB_x86_64-sun-solaris=$(1)-*.dylib.dSYM +CFG_JEMALLOC_CFLAGS_x86_64-sun-solaris := -I/usr/local/include $(CFLAGS) +CFG_GCCISH_CFLAGS_x86_64-sun-solaris := -Wall -Werror -g -D_POSIX_PTHREAD_SEMANTICS -fPIC -I/usr/local/include $(CFLAGS) +CFG_GCCISH_LINK_FLAGS_x86_64-sun-solaris := -shared -fPIC -g -pthread -lrt +CFG_GCCISH_DEF_FLAG_x86_64-sun-solaris := -Wl,--export-dynamic,--dynamic-list= +CFG_LLC_FLAGS_x86_64-sun-solaris := +CFG_INSTALL_NAME_x86_64-sun-solaris = +CFG_EXE_SUFFIX_x86_64-sun-solaris := +CFG_WINDOWSY_x86_64-sun-solaris := +CFG_UNIXY_x86_64-sun-solaris := 1 +CFG_LDPATH_x86_64-sun-solaris := +CFG_RUN_x86_64-sun-solaris=$(2) +CFG_RUN_TARG_x86_64-sun-solaris=$(call CFG_RUN_x86_64-sun-solaris,,$(2)) +CFG_GNU_TRIPLE_x86_64-sun-solaris := x86_64-sun-solaris diff --git a/src/compiletest/util.rs b/src/compiletest/util.rs index 103ca463f7a58..cc40862172691 100644 --- a/src/compiletest/util.rs +++ b/src/compiletest/util.rs @@ -25,6 +25,7 @@ const OS_TABLE: &'static [(&'static str, &'static str)] = &[ ("openbsd", "openbsd"), ("win32", "windows"), ("windows", "windows"), + ("solaris", "solaris"), ]; const ARCH_TABLE: &'static [(&'static str, &'static str)] = &[ diff --git a/src/etc/local_stage0.sh b/src/etc/local_stage0.sh index ca59b1c7d34a2..aee69a5c8bc58 100755 --- a/src/etc/local_stage0.sh +++ b/src/etc/local_stage0.sh @@ -18,7 +18,7 @@ LIB_PREFIX=lib OS=`uname -s` case $OS in - ("Linux"|"FreeBSD"|"DragonFly"|"Bitrig"|"OpenBSD") + ("Linux"|"FreeBSD"|"DragonFly"|"Bitrig"|"OpenBSD"|"SunOS") BIN_SUF= LIB_SUF=.so ;; diff --git a/src/etc/snapshot.py b/src/etc/snapshot.py index 6d62a45c703a2..81babf924c9f9 100644 --- a/src/etc/snapshot.py +++ b/src/etc/snapshot.py @@ -48,6 +48,7 @@ def scrub(b): "macos": ["bin/rustc"], "netbsd": ["bin/rustc"], "openbsd": ["bin/rustc"], + "solaris": ["bin/rustc"], "winnt": ["bin/rustc.exe"], } diff --git a/src/librustc_back/target/mod.rs b/src/librustc_back/target/mod.rs index 39f05ba645e87..4abd8bb339dd4 100644 --- a/src/librustc_back/target/mod.rs +++ b/src/librustc_back/target/mod.rs @@ -59,6 +59,7 @@ mod freebsd_base; mod linux_base; mod openbsd_base; mod netbsd_base; +mod solaris_base; mod windows_base; mod windows_msvc_base; @@ -155,6 +156,10 @@ pub struct TargetOptions { /// Whether the target toolchain is like OSX's. Only useful for compiling against iOS/OS X, in /// particular running dsymutil and some other stuff like `-dead_strip`. Defaults to false. pub is_like_osx: bool, + /// Whether the target toolchain is like Solaris's. + /// Only useful for compiling against Illumos/Solaris, + /// as they have a different set of linker flags. Defaults to false. + pub is_like_solaris: bool, /// Whether the target toolchain is like Windows'. Only useful for compiling against Windows, /// only really used for figuring out how to find libraries, since Windows uses its own /// library naming convention. Defaults to false. @@ -227,6 +232,7 @@ impl Default for TargetOptions { staticlib_suffix: ".a".to_string(), target_family: None, is_like_osx: false, + is_like_solaris: false, is_like_windows: false, is_like_android: false, is_like_msvc: false, @@ -447,6 +453,8 @@ impl Target { armv7_apple_ios, armv7s_apple_ios, + x86_64_sun_solaris, + x86_64_pc_windows_gnu, i686_pc_windows_gnu, diff --git a/src/librustc_back/target/solaris_base.rs b/src/librustc_back/target/solaris_base.rs new file mode 100644 index 0000000000000..bf99a141c106d --- /dev/null +++ b/src/librustc_back/target/solaris_base.rs @@ -0,0 +1,26 @@ +// Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use target::TargetOptions; +use std::default::Default; + +pub fn opts() -> TargetOptions { + TargetOptions { + linker: "cc".to_string(), + dynamic_linking: true, + executables: true, + has_rpath: true, + is_like_solaris: true, + archive_format: "gnu".to_string(), + exe_allocation_crate: super::maybe_jemalloc(), + + .. Default::default() + } +} diff --git a/src/librustc_back/target/x86_64_sun_solaris.rs b/src/librustc_back/target/x86_64_sun_solaris.rs new file mode 100644 index 0000000000000..fbe3f5abc908f --- /dev/null +++ b/src/librustc_back/target/x86_64_sun_solaris.rs @@ -0,0 +1,27 @@ +// Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use target::Target; + +pub fn target() -> Target { + let mut base = super::solaris_base::opts(); + base.pre_link_args.push("-m64".to_string()); + + Target { + llvm_target: "x86_64-pc-solaris".to_string(), + target_endian: "little".to_string(), + target_pointer_width: "64".to_string(), + arch: "x86_64".to_string(), + target_os: "solaris".to_string(), + target_env: "".to_string(), + target_vendor: "sun".to_string(), + options: base, + } +} diff --git a/src/librustc_trans/back/linker.rs b/src/librustc_trans/back/linker.rs index 9c445737b10ee..55192bdf74484 100644 --- a/src/librustc_trans/back/linker.rs +++ b/src/librustc_trans/back/linker.rs @@ -131,6 +131,9 @@ impl<'a> Linker for GnuLinker<'a> { // insert it here. if self.sess.target.target.options.is_like_osx { self.cmd.arg("-Wl,-dead_strip"); + } else if self.sess.target.target.options.is_like_solaris { + self.cmd.arg("-Wl,-z"); + self.cmd.arg("-Wl,ignore"); // If we're building a dylib, we don't use --gc-sections because LLVM // has already done the best it can do, and we also don't want to diff --git a/src/librustdoc/flock.rs b/src/librustdoc/flock.rs index 72a5043178baf..41bcfdb7cb0f0 100644 --- a/src/librustdoc/flock.rs +++ b/src/librustdoc/flock.rs @@ -111,6 +111,25 @@ mod imp { pub const F_SETLKW: libc::c_int = 9; } + #[cfg(target_os = "solaris")] + mod os { + use libc; + + pub struct flock { + pub l_type: libc::c_short, + pub l_whence: libc::c_short, + pub l_start: libc::off_t, + pub l_len: libc::off_t, + pub l_sysid: libc::c_int, + pub l_pid: libc::pid_t, + } + + pub const F_WRLCK: libc::c_short = 2; + pub const F_UNLCK: libc::c_short = 3; + pub const F_SETLK: libc::c_int = 6; + pub const F_SETLKW: libc::c_int = 7; + } + pub struct Lock { fd: libc::c_int, } diff --git a/src/libstd/dynamic_lib.rs b/src/libstd/dynamic_lib.rs index 585051a98e5f7..12edc9ffc64c8 100644 --- a/src/libstd/dynamic_lib.rs +++ b/src/libstd/dynamic_lib.rs @@ -172,7 +172,8 @@ mod tests { target_os = "dragonfly", target_os = "bitrig", target_os = "netbsd", - target_os = "openbsd"))] + target_os = "openbsd", + target_os = "solaris"))] #[allow(deprecated)] fn test_errors_do_not_crash() { use path::Path; @@ -195,7 +196,8 @@ mod tests { target_os = "dragonfly", target_os = "bitrig", target_os = "netbsd", - target_os = "openbsd"))] + target_os = "openbsd", + target_os = "solaris"))] mod dl { use prelude::v1::*; diff --git a/src/libstd/env.rs b/src/libstd/env.rs index db136190082b9..f68500c90e3e5 100644 --- a/src/libstd/env.rs +++ b/src/libstd/env.rs @@ -642,6 +642,7 @@ pub mod consts { /// - bitrig /// - netbsd /// - openbsd + /// - solaris /// - android /// - windows #[stable(feature = "env", since = "1.0.0")] @@ -802,6 +803,17 @@ mod os { pub const EXE_EXTENSION: &'static str = ""; } +#[cfg(target_os = "solaris")] +mod os { + pub const FAMILY: &'static str = "unix"; + pub const OS: &'static str = "solaris"; + pub const DLL_PREFIX: &'static str = "lib"; + pub const DLL_SUFFIX: &'static str = ".so"; + pub const DLL_EXTENSION: &'static str = "so"; + pub const EXE_SUFFIX: &'static str = ""; + pub const EXE_EXTENSION: &'static str = ""; +} + #[cfg(target_os = "windows")] mod os { pub const FAMILY: &'static str = "windows"; diff --git a/src/libstd/num/f64.rs b/src/libstd/num/f64.rs index b6a85ee0e9f58..a39311f7d108d 100644 --- a/src/libstd/num/f64.rs +++ b/src/libstd/num/f64.rs @@ -511,7 +511,7 @@ impl f64 { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn ln(self) -> f64 { - unsafe { intrinsics::logf64(self) } + self.log_wrapper(|n| { unsafe { intrinsics::logf64(n) } }) } /// Returns the logarithm of the number with respect to an arbitrary base. @@ -546,7 +546,7 @@ impl f64 { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn log2(self) -> f64 { - unsafe { intrinsics::log2f64(self) } + self.log_wrapper(|n| { unsafe { intrinsics::log2f64(n) } }) } /// Returns the base 10 logarithm of the number. @@ -562,7 +562,7 @@ impl f64 { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn log10(self) -> f64 { - unsafe { intrinsics::log10f64(self) } + self.log_wrapper(|n| { unsafe { intrinsics::log10f64(n) } }) } /// Converts radians to degrees. @@ -1065,6 +1065,31 @@ impl f64 { pub fn atanh(self) -> f64 { 0.5 * ((2.0 * self) / (1.0 - self)).ln_1p() } + + // Solaris/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 = "solaris") { + 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/os/mod.rs b/src/libstd/os/mod.rs index 84b7d9fbeec93..5606c127dcb0a 100644 --- a/src/libstd/os/mod.rs +++ b/src/libstd/os/mod.rs @@ -30,5 +30,6 @@ pub use sys::ext as windows; #[cfg(target_os = "nacl")] pub mod nacl; #[cfg(target_os = "netbsd")] pub mod netbsd; #[cfg(target_os = "openbsd")] pub mod openbsd; +#[cfg(target_os = "solaris")] pub mod solaris; pub mod raw; diff --git a/src/libstd/os/solaris/mod.rs b/src/libstd/os/solaris/mod.rs new file mode 100644 index 0000000000000..f265233bd54a5 --- /dev/null +++ b/src/libstd/os/solaris/mod.rs @@ -0,0 +1,21 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Solaris-specific definitions + +#![stable(feature = "raw_ext", since = "1.1.0")] + +pub mod raw; + +#[stable(feature = "raw_ext", since = "1.1.0")] +pub mod fs { + #[stable(feature = "raw_ext", since = "1.1.0")] + pub use sys::fs::MetadataExt; +} diff --git a/src/libstd/os/solaris/raw.rs b/src/libstd/os/solaris/raw.rs new file mode 100644 index 0000000000000..cf46ae4a3600d --- /dev/null +++ b/src/libstd/os/solaris/raw.rs @@ -0,0 +1,68 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Solaris-specific raw type definitions + +#![stable(feature = "raw_ext", since = "1.1.0")] + +use os::raw::c_long; +use os::unix::raw::{uid_t, gid_t}; + +#[stable(feature = "raw_ext", since = "1.1.0")] pub type blkcnt_t = i64; +#[stable(feature = "raw_ext", since = "1.1.0")] pub type blksize_t = u32; +#[stable(feature = "raw_ext", since = "1.1.0")] pub type dev_t = u64; +#[stable(feature = "raw_ext", since = "1.1.0")] pub type fflags_t = u32; +#[stable(feature = "raw_ext", since = "1.1.0")] pub type ino_t = i64; +#[stable(feature = "raw_ext", since = "1.1.0")] pub type mode_t = u32; +#[stable(feature = "raw_ext", since = "1.1.0")] pub type nlink_t = u32; +#[stable(feature = "raw_ext", since = "1.1.0")] pub type off_t = i64; +#[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = i64; + +#[unstable(feature = "pthread_t", issue = "29791")] pub type pthread_t = usize; + +#[repr(C)] +#[derive(Clone)] +#[stable(feature = "raw_ext", since = "1.1.0")] +pub struct stat { + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_dev: dev_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_ino: ino_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_mode: mode_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_nlink: nlink_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_uid: uid_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_gid: gid_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_rdev: dev_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_size: off_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_atime: time_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_atime_nsec: c_long, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_mtime: time_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_mtime_nsec: c_long, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_ctime: time_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_ctime_nsec: c_long, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_blksize: blksize_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_blocks: blkcnt_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub __unused: [u8; 16] +} diff --git a/src/libstd/rtdeps.rs b/src/libstd/rtdeps.rs index 9b1046f39a7b3..b1b9ffc4dc63d 100644 --- a/src/libstd/rtdeps.rs +++ b/src/libstd/rtdeps.rs @@ -39,6 +39,12 @@ extern {} #[link(name = "pthread")] extern {} +#[cfg(target_os = "solaris")] +#[link(name = "socket")] +#[link(name = "posix4")] +#[link(name = "pthread")] +extern {} + // For PNaCl targets, nacl_io is a Pepper wrapper for some IO functions // missing (ie always error) in Newlib. #[cfg(all(target_os = "nacl", not(test)))] diff --git a/src/libstd/sys/common/args.rs b/src/libstd/sys/common/args.rs index 4cfddb036e9c2..4600983eb3b80 100644 --- a/src/libstd/sys/common/args.rs +++ b/src/libstd/sys/common/args.rs @@ -38,7 +38,8 @@ pub fn clone() -> Option>> { 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 179a27a2ec86c..f68e22cc67b29 100644 --- a/src/libstd/sys/common/libunwind.rs +++ b/src/libstd/sys/common/libunwind.rs @@ -102,6 +102,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 e09f4ca27bca6..94775341c3898 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 d2d2ce35d84a0..bbc4be9c68a97 100644 --- a/src/libstd/sys/unix/fs.rs +++ b/src/libstd/sys/unix/fs.rs @@ -14,8 +14,7 @@ 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; @@ -25,6 +24,10 @@ use sys::platform::raw; use sys::{cvt, cvt_r}; use sys_common::{AsInner, FromInner}; use vec::Vec; +#[cfg(target_os = "solaris")] +use core_collections::borrow::ToOwned; +#[cfg(target_os = "solaris")] +use boxed::Box; pub struct File(FileDesc); @@ -46,6 +49,12 @@ unsafe impl Sync for Dir {} pub struct DirEntry { entry: dirent, root: Arc, + // 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 +141,36 @@ impl FromInner for FilePermissions { impl Iterator for ReadDir { type Item = io::Result; + #[cfg(target_os = "solaris")] + 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 + } + + 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> { unsafe { let mut ret = DirEntry { @@ -140,7 +179,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 +213,12 @@ impl DirEntry { lstat(&self.path()) } + #[cfg(target_os = "solaris")] + pub fn file_type(&self) -> io::Result { + stat(&self.path()).map(|m| m.file_type()) + } + + #[cfg(not(target_os = "solaris"))] pub fn file_type(&self) -> io::Result { match self.entry.d_type { libc::DT_CHR => Ok(FileType { mode: libc::S_IFCHR }), @@ -189,7 +234,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 } @@ -234,6 +280,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 2e89becfa67e6..f8a4bcdecd73e 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 c62960d74cb1c..fc1fea4bc71e5 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 { } } +#[cfg(any(target_os = "solaris"))] +pub fn current_exe() -> io::Result { + 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(::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, _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; @@ -481,6 +507,28 @@ pub fn home_dir() -> Option { fallback() }).map(PathBuf::from); + #[cfg(not(target_os = "solaris"))] + unsafe fn getpwduid_r(me: libc::uid_t, passwd: &mut libc::passwd, + buf: &mut Vec) -> 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) -> 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(()) } + } + #[cfg(any(target_os = "android", target_os = "ios", target_os = "nacl"))] @@ -497,16 +545,14 @@ pub fn home_dir() -> Option { 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 4a91cece143a9..68147c3659178 100644 --- a/src/libstd/sys/unix/process.rs +++ b/src/libstd/sys/unix/process.rs @@ -93,7 +93,7 @@ fn os2c(s: &OsStr) -> CString { 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 c7614db329959..684924c92798f 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 { @@ -167,6 +168,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 0faa1465c324a..277aa5f19f0aa 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 { 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 { + 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 { Some((libc::pthread_get_stackaddr_np(libc::pthread_self()) as libc::size_t - diff --git a/src/libsyntax/abi.rs b/src/libsyntax/abi.rs index a16f232f4a1c1..0df143c45ae7d 100644 --- a/src/libsyntax/abi.rs +++ b/src/libsyntax/abi.rs @@ -28,6 +28,7 @@ pub enum Os { OsNetbsd, OsOpenbsd, OsNaCl, + OsSolaris, } #[derive(PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Clone, Copy, Debug)] @@ -147,6 +148,7 @@ impl fmt::Display for Os { OsNetbsd => "netbsd".fmt(f), OsOpenbsd => "openbsd".fmt(f), OsNaCl => "nacl".fmt(f), + OsSolaris => "solaris".fmt(f), } } } diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index 130ce3a9637f3..b64b84df062e5 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -927,7 +927,8 @@ fn get_concurrency() -> usize { #[cfg(any(target_os = "linux", target_os = "macos", target_os = "ios", - target_os = "android"))] + target_os = "android", + target_os = "solaris"))] fn num_cpus() -> usize { unsafe { libc::sysconf(libc::_SC_NPROCESSORS_ONLN) as usize } } diff --git a/src/test/debuginfo/gdb-pretty-struct-and-enums-pre-gdb-7-7.rs b/src/test/debuginfo/gdb-pretty-struct-and-enums-pre-gdb-7-7.rs index 5dd428119569d..81743a367e40f 100644 --- a/src/test/debuginfo/gdb-pretty-struct-and-enums-pre-gdb-7-7.rs +++ b/src/test/debuginfo/gdb-pretty-struct-and-enums-pre-gdb-7-7.rs @@ -9,6 +9,7 @@ // except according to those terms. // ignore-bitrig +// ignore-solaris // ignore-windows failing on win32 bot // ignore-freebsd: gdb package too new // ignore-tidy-linelength diff --git a/src/test/run-make/issue-22131/Makefile b/src/test/run-make/issue-22131/Makefile index 0f927320c4e58..ec1e282666a3e 100644 --- a/src/test/run-make/issue-22131/Makefile +++ b/src/test/run-make/issue-22131/Makefile @@ -4,4 +4,4 @@ all: foo.rs $(RUSTC) --cfg 'feature="bar"' --crate-type lib foo.rs $(HOST_RPATH_ENV) $(RUSTDOC) --test --cfg 'feature="bar"' \ -L $(TMPDIR) foo.rs |\ - grep --quiet 'test foo_0 ... ok' + grep -q 'test foo_0 ... ok' diff --git a/src/test/run-make/target-specs/Makefile b/src/test/run-make/target-specs/Makefile index 462665a9c82b9..0c9a0169c1abb 100644 --- a/src/test/run-make/target-specs/Makefile +++ b/src/test/run-make/target-specs/Makefile @@ -2,7 +2,7 @@ all: $(RUSTC) foo.rs --target=my-awesome-platform.json --crate-type=lib --emit=asm grep -q -v morestack < $(TMPDIR)/foo.s - $(RUSTC) foo.rs --target=my-invalid-platform.json 2>&1 | grep --quiet "Error loading target specification" + $(RUSTC) foo.rs --target=my-invalid-platform.json 2>&1 | grep -q "Error loading target specification" $(RUSTC) foo.rs --target=my-incomplete-platform.json 2>&1 | grep 'Field llvm-target' RUST_TARGET_PATH=. $(RUSTC) foo.rs --target=my-awesome-platform --crate-type=lib --emit=asm RUST_TARGET_PATH=. $(RUSTC) foo.rs --target=x86_64-unknown-linux-gnu --crate-type=lib --emit=asm diff --git a/src/test/run-make/tools.mk b/src/test/run-make/tools.mk index 8be34ce427460..dab6511eb9d70 100644 --- a/src/test/run-make/tools.mk +++ b/src/test/run-make/tools.mk @@ -83,6 +83,9 @@ ifeq ($(UNAME),Bitrig) EXTRACFLAGS := -lm -lpthread EXTRACXXFLAGS := -lc++ -lc++abi else +ifeq ($(UNAME),SunOS) + EXTRACFLAGS := -lm -lpthread -lposix4 -lsocket +else ifeq ($(UNAME),OpenBSD) EXTRACFLAGS := -lm -lpthread RUSTC := $(RUSTC) -C linker="$(word 1,$(CC:ccache=))" @@ -94,6 +97,7 @@ endif endif endif endif +endif REMOVE_DYLIBS = rm $(TMPDIR)/$(call DYLIB_GLOB,$(1)) REMOVE_RLIBS = rm $(TMPDIR)/$(call RLIB_GLOB,$(1)) diff --git a/src/test/run-make/use-extern-for-plugins/Makefile b/src/test/run-make/use-extern-for-plugins/Makefile index c67bd3d82ef6b..cc7bc176f49f5 100644 --- a/src/test/run-make/use-extern-for-plugins/Makefile +++ b/src/test/run-make/use-extern-for-plugins/Makefile @@ -1,6 +1,6 @@ -include ../tools.mk -SKIP_OS := 'FreeBSD OpenBSD Bitrig' +SKIP_OS := 'FreeBSD OpenBSD Bitrig SunOS' ifneq ($(UNAME),$(findstring $(UNAME),$(SKIP_OS))) diff --git a/src/test/run-pass/intrinsic-alignment.rs b/src/test/run-pass/intrinsic-alignment.rs index a4720d48213ce..f1e4f8dfa8c83 100644 --- a/src/test/run-pass/intrinsic-alignment.rs +++ b/src/test/run-pass/intrinsic-alignment.rs @@ -23,7 +23,8 @@ mod rusti { target_os = "freebsd", target_os = "dragonfly", target_os = "netbsd", - target_os = "openbsd"))] + target_os = "openbsd", + target_os = "solaris"))] mod m { #[main] #[cfg(target_arch = "x86")] diff --git a/src/test/run-pass/rec-align-u64.rs b/src/test/run-pass/rec-align-u64.rs index 25cd77845ea03..2161864f0b696 100644 --- a/src/test/run-pass/rec-align-u64.rs +++ b/src/test/run-pass/rec-align-u64.rs @@ -41,7 +41,8 @@ struct Outer { target_os = "freebsd", target_os = "dragonfly", target_os = "netbsd", - target_os = "openbsd"))] + target_os = "openbsd", + target_os = "solaris"))] mod m { #[cfg(target_arch = "x86")] pub mod m { diff --git a/src/test/run-pass/x86stdcall.rs b/src/test/run-pass/x86stdcall.rs index 62cbb76c30950..c8c96b299fac0 100644 --- a/src/test/run-pass/x86stdcall.rs +++ b/src/test/run-pass/x86stdcall.rs @@ -37,5 +37,6 @@ pub fn main() { target_os = "bitrig", target_os = "netbsd", target_os = "openbsd", - target_os = "android"))] + target_os = "android", + target_os = "solaris"))] pub fn main() { }