about summary refs log tree commit diff
path: root/src/libstd/sys/unix
diff options
context:
space:
mode:
authorAaron Turon <aturon@mozilla.com>2014-11-24 16:21:39 -0800
committerAaron Turon <aturon@mozilla.com>2014-12-18 23:31:34 -0800
commit74d07699938b846703ab552f52cd5c32f751900f (patch)
tree692dd24ed1e8ee2091ec6728ac17c7f7d4063659 /src/libstd/sys/unix
parent2b3477d373603527d23cc578f3737857b7b253d7 (diff)
downloadrust-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.rs135
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
+    }
+}