Auto merge of #31078 - nbaksalyar:illumos, r=alexcrichton
This pull request adds support for [Illumos](http://illumos.org/)-based operating systems: SmartOS, OpenIndiana, and others. For now it's x86-64 only, as I'm not sure if 32-bit installations are widespread. This PR is based on #28589 by @potatosalad, and also closes #21000, #25845, and #25846. Required changes in libc are already merged: https://github.com/rust-lang-nursery/libc/pull/138 Here's a snapshot required to build a stage0 compiler: https://s3-eu-west-1.amazonaws.com/nbaksalyar/rustc-sunos-snapshot.tar.gz It passes all checks from `make check`. There are some changes I'm not quite sure about, e.g. macro usage in `src/libstd/num/f64.rs` and `DirEntry` structure in `src/libstd/sys/unix/fs.rs`, so any comments on how to rewrite it better would be greatly appreciated. Also, LLVM configure script might need to be patched to build it successfully, or a pre-built libLLVM should be used. Some details can be found here: https://llvm.org/bugs/show_bug.cgi?id=25409 Thanks! r? @brson
This commit is contained in:
commit
e3bcddb44b
36 changed files with 412 additions and 38 deletions
|
@ -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 {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue