about summary refs log tree commit diff
diff options
context:
space:
mode:
authorZiad Hatahet <hatahet@gmail.com>2013-10-22 18:25:07 -0700
committerZiad Hatahet <hatahet@gmail.com>2013-10-22 18:25:07 -0700
commit60245b9290388671edac86d6db1619f60a9ccb68 (patch)
treeb2014dac3d775c584a6319df198b58b0cbdca0b9
parentb477f7a7b74615bba9ab3074082f9cc76a24e8a3 (diff)
downloadrust-60245b9290388671edac86d6db1619f60a9ccb68.tar.gz
rust-60245b9290388671edac86d6db1619f60a9ccb68.zip
Remove thread-blocking call to `libc::stat` in `Path::stat`
Fixes #9958
-rw-r--r--src/librustpkg/conditions.rs5
-rw-r--r--src/librustpkg/util.rs4
-rw-r--r--src/librustpkg/workcache_support.rs14
-rw-r--r--src/libstd/path/mod.rs224
-rw-r--r--src/libstd/path/posix.rs68
-rw-r--r--src/libstd/path/windows.rs47
-rw-r--r--src/libstd/rt/io/file.rs4
-rw-r--r--src/libstd/rt/io/mod.rs6
-rw-r--r--src/libstd/rt/uv/uvio.rs3
-rw-r--r--src/libstd/run.rs8
10 files changed, 65 insertions, 318 deletions
diff --git a/src/librustpkg/conditions.rs b/src/librustpkg/conditions.rs
index 19b310b4506..01bd4e6736e 100644
--- a/src/librustpkg/conditions.rs
+++ b/src/librustpkg/conditions.rs
@@ -12,15 +12,14 @@
 
 pub use std::path::Path;
 pub use package_id::PkgId;
-pub use std::libc;
-pub use std::libc::stat;
+pub use std::rt::io::FileStat;
 
 condition! {
     pub bad_path: (Path, ~str) -> Path;
 }
 
 condition! {
-    pub bad_stat: (Path, ~str) -> stat;
+    pub bad_stat: (Path, ~str) -> FileStat;
 }
 
 condition! {
diff --git a/src/librustpkg/util.rs b/src/librustpkg/util.rs
index a3a4a07cfc7..9144c08cb73 100644
--- a/src/librustpkg/util.rs
+++ b/src/librustpkg/util.rs
@@ -1,4 +1,4 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -609,7 +609,7 @@ fn debug_flags() -> ~[~str] { ~[] }
 /// Returns the last-modified date as an Option
 pub fn datestamp(p: &Path) -> Option<libc::time_t> {
     debug!("Scrutinizing datestamp for {} - does it exist? {:?}", p.display(), os::path_exists(p));
-    let out = p.stat().map(|stat| stat.st_mtime);
+    let out = p.stat().map(|stat| stat.modified);
     debug!("Date = {:?}", out);
     out.map(|t| { t as libc::time_t })
 }
diff --git a/src/librustpkg/workcache_support.rs b/src/librustpkg/workcache_support.rs
index 0352067a7e9..d49a581e070 100644
--- a/src/librustpkg/workcache_support.rs
+++ b/src/librustpkg/workcache_support.rs
@@ -18,17 +18,17 @@ pub fn digest_file_with_date(path: &Path) -> ~str {
     use conditions::bad_path::cond;
     use cond1 = conditions::bad_stat::cond;
 
-    let mut sha = ~Sha1::new();
     let s = io::read_whole_file_str(path);
     match s {
         Ok(s) => {
-            (*sha).input_str(s);
+            let mut sha = Sha1::new();
+            sha.input_str(s);
             let st = match path.stat() {
                 Some(st) => st,
                 None => cond1.raise((path.clone(), format!("Couldn't get file access time")))
             };
-            (*sha).input_str(st.st_mtime.to_str());
-            (*sha).result_str()
+            sha.input_str(st.modified.to_str());
+            sha.result_str()
         }
         Err(e) => {
             let path = cond.raise((path.clone(), format!("Couldn't read file: {}", e)));
@@ -43,13 +43,13 @@ pub fn digest_file_with_date(path: &Path) -> ~str {
 pub fn digest_only_date(path: &Path) -> ~str {
     use cond = conditions::bad_stat::cond;
 
-    let mut sha = ~Sha1::new();
+    let mut sha = Sha1::new();
     let st = match path.stat() {
                 Some(st) => st,
                 None => cond.raise((path.clone(), format!("Couldn't get file access time")))
     };
-    (*sha).input_str(st.st_mtime.to_str());
-    (*sha).result_str()
+    sha.input_str(st.modified.to_str());
+    sha.result_str()
 }
 
 /// Adds multiple discovered outputs
diff --git a/src/libstd/path/mod.rs b/src/libstd/path/mod.rs
index f71f67a30db..18f137e8b0e 100644
--- a/src/libstd/path/mod.rs
+++ b/src/libstd/path/mod.rs
@@ -688,228 +688,6 @@ fn from_utf8_with_replacement(mut v: &[u8]) -> ~str {
     }
     s
 }
-
-// FIXME (#9537): libc::stat should derive Default
-#[cfg(target_os = "linux")]
-#[cfg(target_os = "android")]
-mod stat {
-    #[allow(missing_doc)];
-
-    #[cfg(target_arch = "x86")]
-    pub mod arch {
-        use libc;
-
-        pub fn default_stat() -> libc::stat {
-            libc::stat {
-                st_dev: 0,
-                __pad1: 0,
-                st_ino: 0,
-                st_mode: 0,
-                st_nlink: 0,
-                st_uid: 0,
-                st_gid: 0,
-                st_rdev: 0,
-                __pad2: 0,
-                st_size: 0,
-                st_blksize: 0,
-                st_blocks: 0,
-                st_atime: 0,
-                st_atime_nsec: 0,
-                st_mtime: 0,
-                st_mtime_nsec: 0,
-                st_ctime: 0,
-                st_ctime_nsec: 0,
-                __unused4: 0,
-                __unused5: 0,
-            }
-        }
-    }
-
-    #[cfg(target_arch = "arm")]
-    pub mod arch {
-        use libc;
-
-        pub fn default_stat() -> libc::stat {
-            libc::stat {
-                st_dev: 0,
-                __pad0: [0, ..4],
-                __st_ino: 0,
-                st_mode: 0,
-                st_nlink: 0,
-                st_uid: 0,
-                st_gid: 0,
-                st_rdev: 0,
-                __pad3: [0, ..4],
-                st_size: 0,
-                st_blksize: 0,
-                st_blocks: 0,
-                st_atime: 0,
-                st_atime_nsec: 0,
-                st_mtime: 0,
-                st_mtime_nsec: 0,
-                st_ctime: 0,
-                st_ctime_nsec: 0,
-                st_ino: 0
-            }
-        }
-    }
-
-    #[cfg(target_arch = "mips")]
-    pub mod arch {
-        use libc;
-
-        pub fn default_stat() -> libc::stat {
-            libc::stat {
-                st_dev: 0,
-                st_pad1: [0, ..3],
-                st_ino: 0,
-                st_mode: 0,
-                st_nlink: 0,
-                st_uid: 0,
-                st_gid: 0,
-                st_rdev: 0,
-                st_pad2: [0, ..2],
-                st_size: 0,
-                st_pad3: 0,
-                st_atime: 0,
-                st_atime_nsec: 0,
-                st_mtime: 0,
-                st_mtime_nsec: 0,
-                st_ctime: 0,
-                st_ctime_nsec: 0,
-                st_blksize: 0,
-                st_blocks: 0,
-                st_pad5: [0, ..14],
-            }
-        }
-    }
-
-    #[cfg(target_arch = "x86_64")]
-    pub mod arch {
-        use libc;
-
-        pub fn default_stat() -> libc::stat {
-            libc::stat {
-                st_dev: 0,
-                st_ino: 0,
-                st_nlink: 0,
-                st_mode: 0,
-                st_uid: 0,
-                st_gid: 0,
-                __pad0: 0,
-                st_rdev: 0,
-                st_size: 0,
-                st_blksize: 0,
-                st_blocks: 0,
-                st_atime: 0,
-                st_atime_nsec: 0,
-                st_mtime: 0,
-                st_mtime_nsec: 0,
-                st_ctime: 0,
-                st_ctime_nsec: 0,
-                __unused: [0, 0, 0],
-            }
-        }
-    }
-}
-
-#[cfg(target_os = "freebsd")]
-mod stat {
-    #[allow(missing_doc)];
-
-    #[cfg(target_arch = "x86_64")]
-    pub mod arch {
-        use libc;
-
-        pub fn default_stat() -> libc::stat {
-            libc::stat {
-                st_dev: 0,
-                st_ino: 0,
-                st_mode: 0,
-                st_nlink: 0,
-                st_uid: 0,
-                st_gid: 0,
-                st_rdev: 0,
-                st_atime: 0,
-                st_atime_nsec: 0,
-                st_mtime: 0,
-                st_mtime_nsec: 0,
-                st_ctime: 0,
-                st_ctime_nsec: 0,
-                st_size: 0,
-                st_blocks: 0,
-                st_blksize: 0,
-                st_flags: 0,
-                st_gen: 0,
-                st_lspare: 0,
-                st_birthtime: 0,
-                st_birthtime_nsec: 0,
-                __unused: [0, 0],
-            }
-        }
-    }
-}
-
-#[cfg(target_os = "macos")]
-mod stat {
-    #[allow(missing_doc)];
-
-    pub mod arch {
-        use libc;
-
-        pub fn default_stat() -> libc::stat {
-            libc::stat {
-                st_dev: 0,
-                st_mode: 0,
-                st_nlink: 0,
-                st_ino: 0,
-                st_uid: 0,
-                st_gid: 0,
-                st_rdev: 0,
-                st_atime: 0,
-                st_atime_nsec: 0,
-                st_mtime: 0,
-                st_mtime_nsec: 0,
-                st_ctime: 0,
-                st_ctime_nsec: 0,
-                st_birthtime: 0,
-                st_birthtime_nsec: 0,
-                st_size: 0,
-                st_blocks: 0,
-                st_blksize: 0,
-                st_flags: 0,
-                st_gen: 0,
-                st_lspare: 0,
-                st_qspare: [0, 0],
-            }
-        }
-    }
-}
-
-#[cfg(target_os = "win32")]
-mod stat {
-    #[allow(missing_doc)];
-
-    pub mod arch {
-        use libc;
-        pub fn default_stat() -> libc::stat {
-            libc::stat {
-                st_dev: 0,
-                st_ino: 0,
-                st_mode: 0,
-                st_nlink: 0,
-                st_uid: 0,
-                st_gid: 0,
-                st_rdev: 0,
-                st_size: 0,
-                st_atime: 0,
-                st_mtime: 0,
-                st_ctime: 0,
-            }
-        }
-    }
-}
-
 #[cfg(test)]
 mod tests {
     use super::{GenericPath, PosixPath, WindowsPath};
@@ -921,7 +699,7 @@ mod tests {
         let path: PosixPath = PosixPath::new(input.to_c_str());
         assert_eq!(path.as_vec(), input.as_bytes());
 
-        let input = "\\foo\\bar\\baz";
+        let input = r"\foo\bar\baz";
         let path: WindowsPath = WindowsPath::new(input.to_c_str());
         assert_eq!(path.as_str().unwrap(), input.as_slice());
     }
diff --git a/src/libstd/path/posix.rs b/src/libstd/path/posix.rs
index 87821105d37..d92c2974f76 100644
--- a/src/libstd/path/posix.rs
+++ b/src/libstd/path/posix.rs
@@ -25,7 +25,7 @@ use vec::{CopyableVector, RSplitIterator, SplitIterator, Vector, VectorVector};
 use super::{BytesContainer, GenericPath, GenericPathUnsafe};
 
 #[cfg(not(target_os = "win32"))]
-use libc;
+use rt::io::{FileStat, file, io_error};
 
 /// Iterator that yields successive components of a Path as &[u8]
 pub type ComponentIter<'self> = SplitIterator<'self, u8>;
@@ -445,16 +445,13 @@ static dot_dot_static: &'static [u8] = bytes!("..");
 // Stat support
 #[cfg(not(target_os = "win32"))]
 impl Path {
-    /// Calls stat() on the represented file and returns the resulting libc::stat
-    pub fn stat(&self) -> Option<libc::stat> {
-        #[fixed_stack_segment]; #[inline(never)];
-        do self.with_c_str |buf| {
-            let mut st = super::stat::arch::default_stat();
-            match unsafe { libc::stat(buf as *libc::c_char, &mut st) } {
-                0 => Some(st),
-                _ => None
-            }
+    /// Calls stat() on the represented file and returns the resulting rt::io::FileStat
+    pub fn stat(&self) -> Option<FileStat> {
+        let mut file_stat: Option<FileStat> = None;
+        do io_error::cond.trap(|_| { /* Ignore error, will return None */ }).inside {
+            file_stat = file::stat(self);
         }
+        file_stat
     }
 
     /// Returns whether the represented file exists
@@ -466,10 +463,10 @@ impl Path {
     }
 
     /// Returns the filesize of the represented file
-    pub fn get_size(&self) -> Option<i64> {
+    pub fn get_size(&self) -> Option<u64> {
         match self.stat() {
             None => None,
-            Some(st) => Some(st.st_size as i64)
+            Some(st) => Some(st.size)
         }
     }
 
@@ -477,7 +474,7 @@ impl Path {
     pub fn get_mode(&self) -> Option<uint> {
         match self.stat() {
             None => None,
-            Some(st) => Some(st.st_mode as uint)
+            Some(st) => Some(st.mode as uint)
         }
     }
 }
@@ -486,54 +483,27 @@ impl Path {
 #[cfg(target_os = "linux")]
 #[cfg(target_os = "macos")]
 impl Path {
-    /// Returns the atime of the represented file, as (secs, nsecs)
-    pub fn get_atime(&self) -> Option<(i64, int)> {
-        match self.stat() {
-            None => None,
-            Some(st) => Some((st.st_atime as i64, st.st_atime_nsec as int))
-        }
-    }
-
-    /// Returns the mtime of the represented file, as (secs, nsecs)
-    pub fn get_mtime(&self) -> Option<(i64, int)> {
+    /// Returns the atime of the represented file, as msecs
+    pub fn get_atime(&self) -> Option<u64> {
         match self.stat() {
             None => None,
-            Some(st) => Some((st.st_mtime as i64, st.st_mtime_nsec as int))
+            Some(st) => Some(st.accessed)
         }
     }
 
-    /// Returns the ctime of the represented file, as (secs, nsecs)
-    pub fn get_ctime(&self) -> Option<(i64, int)> {
+    /// Returns the mtime of the represented file, as msecs
+    pub fn get_mtime(&self) -> Option<u64> {
         match self.stat() {
             None => None,
-            Some(st) => Some((st.st_ctime as i64, st.st_ctime_nsec as int))
-        }
-    }
-}
-
-#[cfg(unix)]
-impl Path {
-    /// Calls lstat() on the represented file and returns the resulting libc::stat
-    pub fn lstat(&self) -> Option<libc::stat> {
-        #[fixed_stack_segment]; #[inline(never)];
-        do self.with_c_str |buf| {
-            let mut st = super::stat::arch::default_stat();
-            match unsafe { libc::lstat(buf, &mut st) } {
-                0 => Some(st),
-                _ => None
-            }
+            Some(st) => Some(st.modified)
         }
     }
-}
 
-#[cfg(target_os = "freebsd")]
-#[cfg(target_os = "macos")]
-impl Path {
-    /// Returns the birthtime of the represented file
-    pub fn get_birthtime(&self) -> Option<(i64, int)> {
+    /// Returns the ctime of the represented file, as msecs
+    pub fn get_ctime(&self) -> Option<u64> {
         match self.stat() {
             None => None,
-            Some(st) => Some((st.st_birthtime as i64, st.st_birthtime_nsec as int))
+            Some(st) => Some(st.created)
         }
     }
 }
diff --git a/src/libstd/path/windows.rs b/src/libstd/path/windows.rs
index 0de2bd4c742..dfd654ac13c 100644
--- a/src/libstd/path/windows.rs
+++ b/src/libstd/path/windows.rs
@@ -24,7 +24,7 @@ use vec::Vector;
 use super::{contains_nul, BytesContainer, GenericPath, GenericPathUnsafe};
 
 #[cfg(target_os = "win32")]
-use libc;
+use rt::io::{FileStat, file, io_error};
 
 /// Iterator that yields successive components of a Path as &str
 ///
@@ -1059,16 +1059,13 @@ fn prefix_is_sep(p: Option<PathPrefix>, c: u8) -> bool {
 // Stat support
 #[cfg(target_os = "win32")]
 impl Path {
-    /// Calls stat() on the represented file and returns the resulting libc::stat
-    pub fn stat(&self) -> Option<libc::stat> {
-        #[fixed_stack_segment]; #[inline(never)];
-        do self.with_c_str |buf| {
-            let mut st = super::stat::arch::default_stat();
-            match unsafe { libc::stat(buf, &mut st) } {
-                0 => Some(st),
-                _ => None
-            }
+    /// Calls stat() on the represented file and returns the resulting rt::io::FileStat
+    pub fn stat(&self) -> Option<FileStat> {
+        let mut file_stat: Option<FileStat> = None;
+        do io_error::cond.trap(|_| { /* Ignore error, will return None */ }).inside {
+            file_stat = file::stat(self);
         }
+        file_stat
     }
 
     /// Returns whether the represented file exists
@@ -1080,10 +1077,10 @@ impl Path {
     }
 
     /// Returns the filesize of the represented file
-    pub fn get_size(&self) -> Option<i64> {
+    pub fn get_size(&self) -> Option<u64> {
         match self.stat() {
             None => None,
-            Some(st) => Some(st.st_size as i64)
+            Some(st) => Some(st.size)
         }
     }
 
@@ -1091,37 +1088,31 @@ impl Path {
     pub fn get_mode(&self) -> Option<uint> {
         match self.stat() {
             None => None,
-            Some(st) => Some(st.st_mode as uint)
+            Some(st) => Some(st.mode as uint)
         }
     }
 
-    /// Returns the atime of the represented file, as (secs, nsecs)
-    ///
-    /// nsecs is always 0
-    pub fn get_atime(&self) -> Option<(i64, int)> {
+    /// Returns the atime of the represented file, as msecs
+    pub fn get_atime(&self) -> Option<u64> {
         match self.stat() {
             None => None,
-            Some(st) => Some((st.st_atime as i64, 0))
+            Some(st) => Some(st.accessed)
         }
     }
 
-    /// Returns the mtime of the represented file, as (secs, nsecs)
-    ///
-    /// nsecs is always 0
-    pub fn get_mtime(&self) -> Option<(i64, int)> {
+    /// Returns the mtime of the represented file, as msecs
+    pub fn get_mtime(&self) -> Option<u64> {
         match self.stat() {
             None => None,
-            Some(st) => Some((st.st_mtime as i64, 0))
+            Some(st) => Some(st.modified)
         }
     }
 
-    /// Returns the ctime of the represented file, as (secs, nsecs)
-    ///
-    /// nsecs is always 0
-    pub fn get_ctime(&self) -> Option<(i64, int)> {
+    /// Returns the ctime of the represented file, as msecs
+    pub fn get_ctime(&self) -> Option<u64> {
         match self.stat() {
             None => None,
-            Some(st) => Some((st.st_ctime as i64, 0))
+            Some(st) => Some(st.created)
         }
     }
 }
diff --git a/src/libstd/rt/io/file.rs b/src/libstd/rt/io/file.rs
index a5d593d2454..e25b03be361 100644
--- a/src/libstd/rt/io/file.rs
+++ b/src/libstd/rt/io/file.rs
@@ -59,8 +59,8 @@ use path::Path;
 ///     }).inside {
 ///         let stream = match open(p, Create, ReadWrite) {
 ///             Some(s) => s,
-///             None => fail!("whoops! I'm sure this raised, anyways..");
-///         }
+///             None => fail!("whoops! I'm sure this raised, anyways..")
+///         };
 ///         // do some stuff with that stream
 ///
 ///         // the file stream will be closed at the end of this block
diff --git a/src/libstd/rt/io/mod.rs b/src/libstd/rt/io/mod.rs
index c0971b5d3cd..97d44da765a 100644
--- a/src/libstd/rt/io/mod.rs
+++ b/src/libstd/rt/io/mod.rs
@@ -654,6 +654,12 @@ pub struct FileStat {
     is_file: bool,
     /// `true` if the file pointed at by the `PathInfo` is a directory
     is_dir: bool,
+    /// The file pointed at by the `PathInfo`'s device
+    device: u64,
+    /// The file pointed at by the `PathInfo`'s mode
+    mode: u64,
+    /// The file pointed at by the `PathInfo`'s inode
+    inode: u64,
     /// The file pointed at by the `PathInfo`'s size in bytes
     size: u64,
     /// The file pointed at by the `PathInfo`'s creation time
diff --git a/src/libstd/rt/uv/uvio.rs b/src/libstd/rt/uv/uvio.rs
index d5893d6d014..c7e51b3485d 100644
--- a/src/libstd/rt/uv/uvio.rs
+++ b/src/libstd/rt/uv/uvio.rs
@@ -635,6 +635,9 @@ impl IoFactory for UvIoFactory {
                                 path: Path::new(path_str.as_slice()),
                                 is_file: stat.is_file(),
                                 is_dir: stat.is_dir(),
+                                device: stat.st_dev,
+                                mode: stat.st_mode,
+                                inode: stat.st_ino,
                                 size: stat.st_size,
                                 created: stat.st_ctim.tv_sec as u64,
                                 modified: stat.st_mtim.tv_sec as u64,
diff --git a/src/libstd/run.rs b/src/libstd/run.rs
index a4060586318..36e73a6dd51 100644
--- a/src/libstd/run.rs
+++ b/src/libstd/run.rs
@@ -584,8 +584,8 @@ mod tests {
         let parent_stat = parent_dir.stat().unwrap();
         let child_stat = child_dir.stat().unwrap();
 
-        assert_eq!(parent_stat.st_dev, child_stat.st_dev);
-        assert_eq!(parent_stat.st_ino, child_stat.st_ino);
+        assert_eq!(parent_stat.device, child_stat.device);
+        assert_eq!(parent_stat.inode, child_stat.inode);
     }
 
     #[test]
@@ -601,8 +601,8 @@ mod tests {
         let parent_stat = parent_dir.stat().unwrap();
         let child_stat = child_dir.stat().unwrap();
 
-        assert_eq!(parent_stat.st_dev, child_stat.st_dev);
-        assert_eq!(parent_stat.st_ino, child_stat.st_ino);
+        assert_eq!(parent_stat.device, child_stat.device);
+        assert_eq!(parent_stat.inode, child_stat.inode);
     }
 
     #[cfg(unix,not(target_os="android"))]