diff options
| author | Aaron Turon <aturon@mozilla.com> | 2014-11-24 16:21:39 -0800 |
|---|---|---|
| committer | Aaron Turon <aturon@mozilla.com> | 2014-12-18 23:31:34 -0800 |
| commit | 74d07699938b846703ab552f52cd5c32f751900f (patch) | |
| tree | 692dd24ed1e8ee2091ec6728ac17c7f7d4063659 /src/libstd/sys/unix | |
| parent | 2b3477d373603527d23cc578f3737857b7b253d7 (diff) | |
| download | rust-74d07699938b846703ab552f52cd5c32f751900f.tar.gz rust-74d07699938b846703ab552f52cd5c32f751900f.zip | |
Refactor std::os to use sys::os
Diffstat (limited to 'src/libstd/sys/unix')
| -rw-r--r-- | src/libstd/sys/unix/os.rs | 135 |
1 files changed, 132 insertions, 3 deletions
diff --git a/src/libstd/sys/unix/os.rs b/src/libstd/sys/unix/os.rs index d951977fa59..0ed079df55b 100644 --- a/src/libstd/sys/unix/os.rs +++ b/src/libstd/sys/unix/os.rs @@ -8,14 +8,24 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use libc; -use libc::{c_int, c_char}; +//! Implementation of `std::os` functionality for unix systems + use prelude::*; -use io::IoResult; + +use error::{FromError, Error}; +use fmt; +use io::{IoError, IoResult}; +use libc::{mod, c_int, c_char, c_void}; +use path::{Path, GenericPath, BytesContainer}; +use ptr::{mod, RawPtr}; +use sync::atomic::{AtomicInt, INIT_ATOMIC_INT, SeqCst}; use sys::fs::FileDesc; +use os; use os::TMPBUF_SZ; +const BUF_BYTES : uint = 2048u; + /// Returns the platform-specific value of errno pub fn errno() -> int { #[cfg(any(target_os = "macos", @@ -110,3 +120,122 @@ pub unsafe fn pipe() -> IoResult<(FileDesc, FileDesc)> { Err(super::last_error()) } } + +pub fn getcwd() -> IoResult<Path> { + use c_str::CString; + + let mut buf = [0 as c_char, ..BUF_BYTES]; + unsafe { + if libc::getcwd(buf.as_mut_ptr(), buf.len() as libc::size_t).is_null() { + Err(IoError::last_error()) + } else { + Ok(Path::new(CString::new(buf.as_ptr(), false))) + } + } +} + +pub unsafe fn get_env_pairs() -> Vec<Vec<u8>> { + use c_str::CString; + + extern { + fn rust_env_pairs() -> *const *const c_char; + } + let mut environ = rust_env_pairs(); + if environ as uint == 0 { + panic!("os::env() failure getting env string from OS: {}", + os::last_os_error()); + } + let mut result = Vec::new(); + while *environ != 0 as *const _ { + let env_pair = + CString::new(*environ, false).as_bytes_no_nul().to_vec(); + result.push(env_pair); + environ = environ.offset(1); + } + result +} + +pub fn split_paths(unparsed: &[u8]) -> Vec<Path> { + unparsed.split(|b| *b == b':').map(Path::new).collect() +} + +pub fn join_paths<T: BytesContainer>(paths: &[T]) -> Result<Vec<u8>, &'static str> { + let mut joined = Vec::new(); + let sep = b':'; + + for (i, path) in paths.iter().map(|p| p.container_as_bytes()).enumerate() { + if i > 0 { joined.push(sep) } + if path.contains(&sep) { return Err("path segment contains separator `:`") } + joined.push_all(path); + } + + Ok(joined) +} + +#[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] +pub fn load_self() -> Option<Vec<u8>> { + unsafe { + use libc::funcs::bsd44::*; + use libc::consts::os::extra::*; + let mut mib = vec![CTL_KERN as c_int, + KERN_PROC as c_int, + KERN_PROC_PATHNAME as c_int, + -1 as c_int]; + let mut sz: libc::size_t = 0; + let err = sysctl(mib.as_mut_ptr(), mib.len() as ::libc::c_uint, + ptr::null_mut(), &mut sz, ptr::null_mut(), + 0u as libc::size_t); + if err != 0 { return None; } + if sz == 0 { return None; } + let mut v: Vec<u8> = Vec::with_capacity(sz as uint); + let err = sysctl(mib.as_mut_ptr(), mib.len() as ::libc::c_uint, + v.as_mut_ptr() as *mut c_void, &mut sz, + ptr::null_mut(), 0u as libc::size_t); + if err != 0 { return None; } + if sz == 0 { return None; } + v.set_len(sz as uint - 1); // chop off trailing NUL + Some(v) + } +} + +#[cfg(any(target_os = "linux", target_os = "android"))] +pub fn load_self() -> Option<Vec<u8>> { + use std::io; + + match io::fs::readlink(&Path::new("/proc/self/exe")) { + Ok(path) => Some(path.into_vec()), + Err(..) => None + } +} + +#[cfg(any(target_os = "macos", target_os = "ios"))] +pub fn load_self() -> Option<Vec<u8>> { + unsafe { + use libc::funcs::extra::_NSGetExecutablePath; + let mut sz: u32 = 0; + _NSGetExecutablePath(ptr::null_mut(), &mut sz); + if sz == 0 { return None; } + let mut v: Vec<u8> = Vec::with_capacity(sz as uint); + let err = _NSGetExecutablePath(v.as_mut_ptr() as *mut i8, &mut sz); + if err != 0 { return None; } + v.set_len(sz as uint - 1); // chop off trailing NUL + Some(v) + } +} + +pub fn chdir(p: &Path) -> IoResult<()> { + p.with_c_str(|buf| { + unsafe { + match libc::chdir(buf) == (0 as c_int) { + true => Ok(()), + false => Err(IoError::last_error()), + } + } + }) +} + +pub fn page_size() -> uint { + unsafe { + libc::sysconf(libc::_SC_PAGESIZE) as uint + } +} |
