Skip to content

Commit

Permalink
Auto merge of rust-lang#30175 - alexcrichton:less-c-code, r=brson
Browse files Browse the repository at this point in the history
All these definitions can now be written in Rust, so do so!
  • Loading branch information
bors committed Dec 22, 2015
2 parents 439e184 + 2f42ac4 commit 5178449
Show file tree
Hide file tree
Showing 9 changed files with 156 additions and 666 deletions.
2 changes: 1 addition & 1 deletion mk/crates.mk
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ DEPS_rustc_bitflags := core
DEPS_rustc_unicode := core

DEPS_std := core libc rand alloc collections rustc_unicode \
native:rust_builtin native:backtrace \
native:backtrace \
alloc_system
DEPS_arena := std
DEPS_glob := std
Expand Down
4 changes: 1 addition & 3 deletions mk/rt.mk
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
# that's per-target so you're allowed to conditionally add files based on the
# target.
################################################################################
NATIVE_LIBS := rust_builtin hoedown miniz rust_test_helpers
NATIVE_LIBS := hoedown miniz rust_test_helpers

# $(1) is the target triple
define NATIVE_LIBRARIES
Expand All @@ -50,8 +50,6 @@ NATIVE_DEPS_hoedown_$(1) := hoedown/src/autolink.c \
hoedown/src/stack.c \
hoedown/src/version.c
NATIVE_DEPS_miniz_$(1) = miniz.c
NATIVE_DEPS_rust_builtin_$(1) := rust_builtin.c \
rust_android_dummy.c
NATIVE_DEPS_rust_test_helpers_$(1) := rust_test_helpers.c

################################################################################
Expand Down
11 changes: 11 additions & 0 deletions src/liballoc_jemalloc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,3 +108,14 @@ pub extern "C" fn __rust_usable_size(size: usize, align: usize) -> usize {
let flags = align_to_flags(align);
unsafe { je_nallocx(size as size_t, flags) as usize }
}

// These symbols are used by jemalloc on android but the really old android
// we're building on doesn't have them defined, so just make sure the symbols
// are available.
#[no_mangle]
#[cfg(target_os = "android")]
pub extern fn pthread_atfork(_prefork: *mut u8,
_postfork_parent: *mut u8,
_postfork_child: *mut u8) -> i32 {
0
}
5 changes: 0 additions & 5 deletions src/libstd/rtdeps.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,6 @@
//! the standard library This varies per-platform, but these libraries are
//! necessary for running libstd.
// A few small shims in C that haven't been translated to Rust yet
#[cfg(all(not(test), not(windows)))]
#[link(name = "rust_builtin", kind = "static")]
extern {}

// LLVM implements the `frem` instruction as a call to `fmod`, which lives in
// libm. Hence, we must explicitly link to it.
//
Expand Down
110 changes: 65 additions & 45 deletions src/libstd/sys/unix/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ use os::unix::prelude::*;
use ffi::{CString, CStr, OsString, OsStr};
use fmt;
use io::{self, Error, ErrorKind, SeekFrom};
use libc::{self, c_int, off_t, c_char, mode_t};
use libc::{dirent, readdir_r};
use libc::{self, c_int, off_t, mode_t};
use mem;
use path::{Path, PathBuf};
use ptr;
Expand Down Expand Up @@ -43,7 +44,7 @@ unsafe impl Send for Dir {}
unsafe impl Sync for Dir {}

pub struct DirEntry {
buf: Vec<u8>, // actually *mut libc::dirent
entry: dirent,
root: Arc<PathBuf>,
}

Expand Down Expand Up @@ -126,32 +127,22 @@ impl Iterator for ReadDir {
type Item = io::Result<DirEntry>;

fn next(&mut self) -> Option<io::Result<DirEntry>> {
extern {
fn rust_dirent_t_size() -> libc::size_t;
}

let mut buf: Vec<u8> = Vec::with_capacity(unsafe {
rust_dirent_t_size()
});
let ptr = buf.as_mut_ptr() as *mut libc::dirent;

let mut entry_ptr = ptr::null_mut();
loop {
if unsafe { libc::readdir_r(self.dirp.0, ptr, &mut entry_ptr) != 0 } {
return Some(Err(Error::last_os_error()))
}
if entry_ptr.is_null() {
return None
}

let entry = DirEntry {
buf: buf,
unsafe {
let mut ret = DirEntry {
entry: mem::zeroed(),
root: self.root.clone()
};
if entry.name_bytes() == b"." || entry.name_bytes() == b".." {
buf = entry.buf;
} else {
return Some(Ok(entry))
let mut entry_ptr = ptr::null_mut();
loop {
if readdir_r(self.dirp.0, &mut ret.entry, &mut entry_ptr) != 0 {
return Some(Err(Error::last_os_error()))
}
if entry_ptr.is_null() {
return None
}
if ret.name_bytes() != b"." && ret.name_bytes() != b".." {
return Some(Ok(ret))
}
}
}
}
Expand All @@ -166,7 +157,7 @@ impl Drop for Dir {

impl DirEntry {
pub fn path(&self) -> PathBuf {
self.root.join(<OsStr as OsStrExt>::from_bytes(self.name_bytes()))
self.root.join(OsStr::from_bytes(self.name_bytes()))
}

pub fn file_name(&self) -> OsString {
Expand All @@ -178,35 +169,64 @@ impl DirEntry {
}

pub fn file_type(&self) -> io::Result<FileType> {
extern {
fn rust_dir_get_mode(ptr: *mut libc::dirent) -> c_int;
}
unsafe {
match rust_dir_get_mode(self.dirent()) {
-1 => lstat(&self.path()).map(|m| m.file_type()),
n => Ok(FileType { mode: n as mode_t }),
}
match self.entry.d_type {
libc::DT_CHR => Ok(FileType { mode: libc::S_IFCHR }),
libc::DT_FIFO => Ok(FileType { mode: libc::S_IFIFO }),
libc::DT_LNK => Ok(FileType { mode: libc::S_IFLNK }),
libc::DT_REG => Ok(FileType { mode: libc::S_IFREG }),
libc::DT_SOCK => Ok(FileType { mode: libc::S_IFSOCK }),
libc::DT_DIR => Ok(FileType { mode: libc::S_IFDIR }),
libc::DT_BLK => Ok(FileType { mode: libc::S_IFBLK }),
_ => lstat(&self.path()).map(|m| m.file_type()),
}
}

#[cfg(any(target_os = "macos",
target_os = "ios",
target_os = "linux"))]
pub fn ino(&self) -> raw::ino_t {
extern {
fn rust_dir_get_ino(ptr: *mut libc::dirent) -> raw::ino_t;
}
unsafe { rust_dir_get_ino(self.dirent()) }
self.entry.d_ino
}

#[cfg(target_os = "android")]
pub fn ino(&self) -> raw::ino_t {
self.entry.d_ino as raw::ino_t
}

#[cfg(any(target_os = "freebsd",
target_os = "openbsd",
target_os = "bitrig",
target_os = "netbsd",
target_os = "dragonfly"))]
pub fn ino(&self) -> raw::ino_t {
self.entry.d_fileno
}

#[cfg(any(target_os = "macos",
target_os = "ios",
target_os = "netbsd"))]
fn name_bytes(&self) -> &[u8] {
extern {
fn rust_list_dir_val(ptr: *mut libc::dirent) -> *const c_char;
unsafe {
::slice::from_raw_parts(self.entry.d_name.as_ptr() as *const u8,
self.entry.d_namlen as usize)
}
}
#[cfg(any(target_os = "freebsd",
target_os = "dragonfly",
target_os = "bitrig",
target_os = "openbsd"))]
fn name_bytes(&self) -> &[u8] {
unsafe {
CStr::from_ptr(rust_list_dir_val(self.dirent())).to_bytes()
::slice::from_raw_parts(self.entry.d_name.as_ptr() as *const u8,
self.entry.d_namelen as usize)
}
}

fn dirent(&self) -> *mut libc::dirent {
self.buf.as_ptr() as *mut _
#[cfg(any(target_os = "android",
target_os = "linux"))]
fn name_bytes(&self) -> &[u8] {
unsafe {
CStr::from_ptr(self.entry.d_name.as_ptr()).to_bytes()
}
}
}

Expand Down
67 changes: 40 additions & 27 deletions src/libstd/sys/unix/os.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,17 @@ static ENV_LOCK: StaticMutex = StaticMutex::new();
/// Returns the platform-specific value of errno
pub fn errno() -> i32 {
extern {
#[cfg_attr(any(target_os = "linux", target_os = "android"), link_name = "__errno_location")]
#[cfg_attr(any(target_os = "bitrig", target_os = "netbsd", target_os = "openbsd",
#[cfg_attr(any(target_os = "linux"), link_name = "__errno_location")]
#[cfg_attr(any(target_os = "bitrig",
target_os = "netbsd",
target_os = "openbsd",
target_os = "android",
target_env = "newlib"),
link_name = "__errno")]
#[cfg_attr(target_os = "dragonfly", link_name = "__dfly_error")]
#[cfg_attr(any(target_os = "macos", target_os = "ios", target_os = "freebsd"),
#[cfg_attr(any(target_os = "macos",
target_os = "ios",
target_os = "freebsd"),
link_name = "__error")]
fn errno_location() -> *const c_int;
}
Expand Down Expand Up @@ -173,17 +178,19 @@ pub fn current_exe() -> io::Result<PathBuf> {
libc::KERN_PROC_PATHNAME as c_int,
-1 as c_int];
let mut sz: libc::size_t = 0;
let err = libc::sysctl(mib.as_mut_ptr(), mib.len() as ::libc::c_uint,
ptr::null_mut(), &mut sz, ptr::null_mut(),
0 as libc::size_t);
if err != 0 { return Err(io::Error::last_os_error()); }
if sz == 0 { return Err(io::Error::last_os_error()); }
try!(cvt(libc::sysctl(mib.as_mut_ptr(), mib.len() as ::libc::c_uint,
ptr::null_mut(), &mut sz, ptr::null_mut(),
0 as libc::size_t)));
if sz == 0 {
return Err(io::Error::last_os_error())
}
let mut v: Vec<u8> = Vec::with_capacity(sz as usize);
let err = libc::sysctl(mib.as_mut_ptr(), mib.len() as ::libc::c_uint,
v.as_mut_ptr() as *mut libc::c_void, &mut sz,
ptr::null_mut(), 0 as libc::size_t);
if err != 0 { return Err(io::Error::last_os_error()); }
if sz == 0 { return Err(io::Error::last_os_error()); }
try!(cvt(libc::sysctl(mib.as_mut_ptr(), mib.len() as ::libc::c_uint,
v.as_mut_ptr() as *mut libc::c_void, &mut sz,
ptr::null_mut(), 0 as libc::size_t)));
if sz == 0 {
return Err(io::Error::last_os_error());
}
v.set_len(sz as usize - 1); // chop off trailing NUL
Ok(PathBuf::from(OsString::from_vec(v)))
}
Expand All @@ -201,22 +208,28 @@ pub fn current_exe() -> io::Result<PathBuf> {

#[cfg(any(target_os = "bitrig", target_os = "openbsd"))]
pub fn current_exe() -> io::Result<PathBuf> {
use sync::StaticMutex;
static LOCK: StaticMutex = StaticMutex::new();

extern {
fn rust_current_exe() -> *const c_char;
}

let _guard = LOCK.lock();

unsafe {
let v = rust_current_exe();
if v.is_null() {
Err(io::Error::last_os_error())
let mut mib = [libc::CTL_KERN,
libc::KERN_PROC_ARGS,
libc::getpid(),
libc::KERN_PROC_ARGV];
let mib = mib.as_mut_ptr();
let mut argv_len = 0;
try!(cvt(libc::sysctl(mib, 4, 0 as *mut _, &mut argv_len,
0 as *mut _, 0)));
let mut argv = Vec::<*const libc::c_char>::with_capacity(argv_len as usize);
try!(cvt(libc::sysctl(mib, 4, argv.as_mut_ptr() as *mut _,
&mut argv_len, 0 as *mut _, 0)));
argv.set_len(argv_len as usize);
if argv[0].is_null() {
return Err(io::Error::new(io::ErrorKind::Other,
"no current exe available"))
}
let argv0 = CStr::from_ptr(argv[0]).to_bytes();
if argv0[0] == b'.' || argv0.iter().any(|b| *b == b'/') {
::fs::canonicalize(OsStr::from_bytes(argv0))
} else {
let vec = CStr::from_ptr(v).to_bytes().to_vec();
Ok(PathBuf::from(OsString::from_vec(vec)))
Ok(PathBuf::from(OsStr::from_bytes(argv0)))
}
}
}
Expand Down
41 changes: 38 additions & 3 deletions src/libtest/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -906,10 +906,45 @@ fn get_concurrency() -> usize {
}
}

#[cfg(unix)]
#[cfg(any(target_os = "linux",
target_os = "macos",
target_os = "ios",
target_os = "android"))]
fn num_cpus() -> usize {
extern { fn rust_get_num_cpus() -> libc::uintptr_t; }
unsafe { rust_get_num_cpus() as usize }
unsafe {
libc::sysconf(libc::_SC_NPROCESSORS_ONLN) as usize
}
}

#[cfg(any(target_os = "freebsd",
target_os = "dragonfly",
target_os = "bitrig",
target_os = "openbsd",
target_os = "netbsd"))]
fn num_cpus() -> usize {
let mut cpus: libc::c_uint = 0;
let mut CPUS_SIZE = std::mem::size_of_val(&cpus);
let mut mib = [libc::CTL_HW, libc::HW_AVAILCPU, 0, 0];

unsafe {
libc::sysctl(mib.as_mut_ptr(), 2,
&mut cpus as *mut _ as *mut _,
&mut CPUS_SIZE as *mut _ as *mut _,
0 as *mut _, 0);
}
if cpus < 1 {
mib[1] = HW_NCPU;
unsafe {
libc::sysctl(mib.as_mut_ptr(), 2,
&mut cpus as *mut _ as *mut _,
&mut CPUS_SIZE as *mut _ as *mut _,
0 as *mut _, 0);
}
if cpus < 1 {
cpus = 1;
}
}
cpus as usize
}
}

Expand Down
Loading

0 comments on commit 5178449

Please sign in to comment.