about summary refs log tree commit diff
path: root/src/libstd/sys/unix
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2015-12-02 10:31:29 -0800
committerAlex Crichton <alex@alexcrichton.com>2015-12-21 22:12:48 -0800
commit2f42ac438ef4bc2773f5ac0a55ae45b08e575b17 (patch)
treef91aed3b3f838305d24f1d25441ec22dc6ab995d /src/libstd/sys/unix
parent2343a92a908901958c8207d6d0430a2e59ab0a9c (diff)
downloadrust-2f42ac438ef4bc2773f5ac0a55ae45b08e575b17.tar.gz
rust-2f42ac438ef4bc2773f5ac0a55ae45b08e575b17.zip
std: Remove rust_builtin C support library
All these definitions can now be written in Rust, so do so!
Diffstat (limited to 'src/libstd/sys/unix')
-rw-r--r--src/libstd/sys/unix/fs.rs110
-rw-r--r--src/libstd/sys/unix/os.rs67
2 files changed, 105 insertions, 72 deletions
diff --git a/src/libstd/sys/unix/fs.rs b/src/libstd/sys/unix/fs.rs
index e634c10d8b7..e8575a6c21c 100644
--- a/src/libstd/sys/unix/fs.rs
+++ b/src/libstd/sys/unix/fs.rs
@@ -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;
@@ -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>,
 }
 
@@ -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))
+                }
             }
         }
     }
@@ -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 {
@@ -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()
+        }
     }
 }
 
diff --git a/src/libstd/sys/unix/os.rs b/src/libstd/sys/unix/os.rs
index 12b9d6191a0..c62960d74cb 100644
--- a/src/libstd/sys/unix/os.rs
+++ b/src/libstd/sys/unix/os.rs
@@ -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;
     }
@@ -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)))
     }
@@ -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)))
         }
     }
 }