1
Fork 0

Remove thread-blocking call to libc::stat in Path::stat

Fixes #9958
This commit is contained in:
Ziad Hatahet 2013-10-22 18:25:07 -07:00
parent b477f7a7b7
commit 60245b9290
10 changed files with 65 additions and 318 deletions

View file

@ -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());
}

View file

@ -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)> {
/// 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, st.st_atime_nsec as int))
Some(st) => Some(st.accessed)
}
}
/// Returns the mtime of the represented file, as (secs, nsecs)
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, st.st_mtime_nsec as int))
Some(st) => Some(st.modified)
}
}
/// Returns the ctime of the represented file, as (secs, nsecs)
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, 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
}
}
}
}
#[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)> {
match self.stat() {
None => None,
Some(st) => Some((st.st_birthtime as i64, st.st_birthtime_nsec as int))
Some(st) => Some(st.created)
}
}
}

View file

@ -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)
}
}
}