diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2013-10-31 15:15:30 -0700 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2013-11-04 10:28:55 -0800 |
| commit | 3c3ed1499a9b9e23d4a2d2243a7b0b1c9015f34b (patch) | |
| tree | b349c0b7f6cd8ae46dd05ecc430ecca15ae037c4 | |
| parent | f19d0833625c382c5d0a8868924cd4620335e659 (diff) | |
| download | rust-3c3ed1499a9b9e23d4a2d2243a7b0b1c9015f34b.tar.gz rust-3c3ed1499a9b9e23d4a2d2243a7b0b1c9015f34b.zip | |
Move io::file to io::fs and fns out of File
This renames the `file` module to `fs` because that more accurately describes its current purpose (manipulating the filesystem, not just files). Additionally, this adds an UnstableFileStat structure as a nested structure of FileStat to signify that the fields should not be depended on. The structure is currently flagged with #[unstable], but it's unlikely that it has much meaning. Closes #10241
31 files changed, 491 insertions, 477 deletions
diff --git a/src/compiletest/compiletest.rs b/src/compiletest/compiletest.rs index a354bc84e52..f4bd668690e 100644 --- a/src/compiletest/compiletest.rs +++ b/src/compiletest/compiletest.rs @@ -17,7 +17,7 @@ extern mod extra; use std::os; use std::rt; -use std::rt::io::file; +use std::rt::io::fs; use extra::getopts; use extra::getopts::groups::{optopt, optflag, reqopt}; @@ -248,7 +248,7 @@ pub fn make_tests(config: &config) -> ~[test::TestDescAndFn] { debug!("making tests from {}", config.src_base.display()); let mut tests = ~[]; - let dirs = file::readdir(&config.src_base); + let dirs = fs::readdir(&config.src_base); for file in dirs.iter() { let file = file.clone(); debug!("inspecting file {}", file.display()); diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs index d55bdc23703..1b3e34ad819 100644 --- a/src/compiletest/runtest.rs +++ b/src/compiletest/runtest.rs @@ -20,43 +20,18 @@ use procsrv; use util; use util::logv; -use std::cell::Cell; use std::rt::io; -use std::rt::io::file; +use std::rt::io::fs; use std::rt::io::File; use std::os; use std::str; -use std::task::{spawn_sched, SingleThreaded}; use std::vec; -use std::unstable::running_on_valgrind; use extra::test::MetricMap; pub fn run(config: config, testfile: ~str) { - let config = Cell::new(config); - let testfile = Cell::new(testfile); - // FIXME #6436: Creating another thread to run the test because this - // is going to call waitpid. The new scheduler has some strange - // interaction between the blocking tasks and 'friend' schedulers - // that destroys parallelism if we let normal schedulers block. - // It should be possible to remove this spawn once std::run is - // rewritten to be non-blocking. - // - // We do _not_ create another thread if we're running on V because - // it serializes all threads anyways. - if running_on_valgrind() { - let config = config.take(); - let testfile = testfile.take(); - let mut _mm = MetricMap::new(); - run_metrics(config, testfile, &mut _mm); - } else { - do spawn_sched(SingleThreaded) { - let config = config.take(); - let testfile = testfile.take(); - let mut _mm = MetricMap::new(); - run_metrics(config, testfile, &mut _mm); - } - } + let mut _mm = MetricMap::new(); + run_metrics(config, testfile, &mut _mm); } pub fn run_metrics(config: config, testfile: ~str, mm: &mut MetricMap) { @@ -651,7 +626,7 @@ fn compose_and_run_compiler( fn ensure_dir(path: &Path) { if path.is_dir() { return; } - file::mkdir(path, io::UserRWX); + fs::mkdir(path, io::UserRWX); } fn compose_and_run(config: &config, testfile: &Path, @@ -921,7 +896,7 @@ fn _dummy_exec_compiled_test(config: &config, props: &TestProps, fn _arm_push_aux_shared_library(config: &config, testfile: &Path) { let tdir = aux_output_dir_name(config, testfile); - let dirs = file::readdir(&tdir); + let dirs = fs::readdir(&tdir); for file in dirs.iter() { if file.extension_str() == Some("so") { // FIXME (#9639): This needs to handle non-utf8 paths diff --git a/src/libextra/glob.rs b/src/libextra/glob.rs index a7742f771da..1edef5ddbe1 100644 --- a/src/libextra/glob.rs +++ b/src/libextra/glob.rs @@ -25,7 +25,7 @@ use std::{os, path}; use std::rt::io; -use std::rt::io::file; +use std::rt::io::fs; use std::path::is_sep; use sort; @@ -148,7 +148,7 @@ impl Iterator<Path> for GlobIterator { } fn list_dir_sorted(path: &Path) -> ~[Path] { - match io::result(|| file::readdir(path)) { + match io::result(|| fs::readdir(path)) { Ok(children) => { let mut children = children; sort::quick_sort(children, |p1, p2| p2.filename() <= p1.filename()); diff --git a/src/libextra/tempfile.rs b/src/libextra/tempfile.rs index 4affe7c1cde..fbd65cab98c 100644 --- a/src/libextra/tempfile.rs +++ b/src/libextra/tempfile.rs @@ -15,7 +15,7 @@ use std::os; use std::rand::Rng; use std::rand; use std::rt::io; -use std::rt::io::file; +use std::rt::io::fs; /// A wrapper for a path to temporary directory implementing automatic /// scope-pased deletion. @@ -38,7 +38,7 @@ impl TempDir { let mut r = rand::rng(); for _ in range(0u, 1000) { let p = tmpdir.join(r.gen_ascii_str(16) + suffix); - match io::result(|| file::mkdir(&p, io::UserRWX)) { + match io::result(|| fs::mkdir(&p, io::UserRWX)) { Err(*) => {} Ok(()) => return Some(TempDir { path: Some(p) }) } @@ -73,7 +73,7 @@ impl Drop for TempDir { fn drop(&mut self) { for path in self.path.iter() { if path.exists() { - file::rmdir_recursive(path); + fs::rmdir_recursive(path); } } } diff --git a/src/libextra/terminfo/parser/compiled.rs b/src/libextra/terminfo/parser/compiled.rs index b530c1b6334..04b30e5ef74 100644 --- a/src/libextra/terminfo/parser/compiled.rs +++ b/src/libextra/terminfo/parser/compiled.rs @@ -329,6 +329,6 @@ mod test { #[ignore(reason = "no ncurses on buildbots, needs a bundled terminfo file to test against")] fn test_parse() { // FIXME #6870: Distribute a compiled file in src/tests and test there - // parse(io::file_reader(&p("/usr/share/terminfo/r/rxvt-256color")).unwrap(), false); + // parse(io::fs_reader(&p("/usr/share/terminfo/r/rxvt-256color")).unwrap(), false); } } diff --git a/src/libextra/workcache.rs b/src/libextra/workcache.rs index 09d9dd828d4..eed37a426be 100644 --- a/src/libextra/workcache.rs +++ b/src/libextra/workcache.rs @@ -19,8 +19,7 @@ use std::cell::Cell; use std::comm::{PortOne, oneshot}; use std::{str, task}; use std::rt::io; -use std::rt::io::File; -use std::rt::io::Decorator; +use std::rt::io::{File, Decorator}; use std::rt::io::mem::MemWriter; /** @@ -480,6 +479,7 @@ impl<'self, T:Send + #[test] fn test() { use std::{os, run}; + use std::rt::io::fs; use std::str::from_utf8_owned; // Create a path to a new file 'filename' in the directory in which @@ -487,7 +487,7 @@ fn test() { fn make_path(filename: ~str) -> Path { let pth = os::self_exe_path().expect("workcache::test failed").with_filename(filename); if pth.exists() { - File::unlink(&pth); + fs::unlink(&pth); } return pth; } diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs index 81a20522807..5b0f424360b 100644 --- a/src/librustc/back/link.rs +++ b/src/librustc/back/link.rs @@ -31,7 +31,7 @@ use std::ptr; use std::run; use std::str; use std::vec; -use std::rt::io::File; +use std::rt::io::fs; use syntax::ast; use syntax::ast_map::{path, path_mod, path_name, path_pretty_name}; use syntax::attr; @@ -950,7 +950,7 @@ pub fn link_binary(sess: Session, // Remove the temporary object file if we aren't saving temps if !sess.opts.save_temps { - File::unlink(obj_filename); + fs::unlink(obj_filename); } } diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs index 01035385f97..744e192095b 100644 --- a/src/librustc/driver/driver.rs +++ b/src/librustc/driver/driver.rs @@ -27,7 +27,7 @@ use util::ppaux; use std::hashmap::{HashMap,HashSet}; use std::rt::io; -use std::rt::io::File; +use std::rt::io::fs; use std::rt::io::mem::MemReader; use std::os; use std::vec; @@ -370,7 +370,7 @@ pub fn phase_5_run_llvm_passes(sess: Session, // Remove assembly source unless --save-temps was specified if !sess.opts.save_temps { - File::unlink(&asm_filename); + fs::unlink(&asm_filename); } } else { time(sess.time_passes(), "LLVM passes", (), |_| diff --git a/src/librustc/metadata/filesearch.rs b/src/librustc/metadata/filesearch.rs index 44e43bd4ef3..c9bd5eff4a7 100644 --- a/src/librustc/metadata/filesearch.rs +++ b/src/librustc/metadata/filesearch.rs @@ -12,7 +12,7 @@ use std::option; use std::os; use std::rt::io; -use std::rt::io::file; +use std::rt::io::fs; use std::hashmap::HashSet; pub enum FileMatch { FileMatches, FileDoesntMatch } @@ -119,7 +119,7 @@ pub fn mk_filesearch(maybe_sysroot: &Option<@Path>, pub fn search(filesearch: @FileSearch, pick: pick) { do filesearch.for_each_lib_search_path() |lib_search_path| { debug!("searching {}", lib_search_path.display()); - match io::result(|| file::readdir(lib_search_path)) { + match io::result(|| fs::readdir(lib_search_path)) { Ok(files) => { let mut rslt = FileDoesntMatch; for path in files.iter() { diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index d0e01d1f423..0efc52bbe4a 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -41,7 +41,7 @@ use std::hashmap::{HashMap, HashSet}; use std::local_data; use std::rt::io::buffered::BufferedWriter; use std::rt::io; -use std::rt::io::file; +use std::rt::io::fs; use std::rt::io::File; use std::os; use std::str; @@ -326,7 +326,7 @@ fn mkdir(path: &Path) { fail!() }).inside { if !path.is_dir() { - file::mkdir(path, io::UserRWX); + fs::mkdir(path, io::UserRWX); } } } diff --git a/src/librustpkg/installed_packages.rs b/src/librustpkg/installed_packages.rs index 09b58e6e94c..576d5abe8bd 100644 --- a/src/librustpkg/installed_packages.rs +++ b/src/librustpkg/installed_packages.rs @@ -14,12 +14,12 @@ use rustc::metadata::filesearch::rust_path; use path_util::*; use std::os; use std::rt::io; -use std::rt::io::file; +use std::rt::io::fs; pub fn list_installed_packages(f: &fn(&PkgId) -> bool) -> bool { let workspaces = rust_path(); for p in workspaces.iter() { - let binfiles = do io::ignore_io_error { file::readdir(&p.join("bin")) }; + let binfiles = do io::ignore_io_error { fs::readdir(&p.join("bin")) }; for exec in binfiles.iter() { // FIXME (#9639): This needs to handle non-utf8 paths match exec.filestem_str() { @@ -31,7 +31,7 @@ pub fn list_installed_packages(f: &fn(&PkgId) -> bool) -> bool { } } } - let libfiles = do io::ignore_io_error { file::readdir(&p.join("lib")) }; + let libfiles = do io::ignore_io_error { fs::readdir(&p.join("lib")) }; for lib in libfiles.iter() { debug!("Full name: {}", lib.display()); match has_library(lib) { @@ -55,7 +55,7 @@ pub fn list_installed_packages(f: &fn(&PkgId) -> bool) -> bool { } pub fn has_library(p: &Path) -> Option<~str> { - let files = do io::ignore_io_error { file::readdir(p) }; + let files = do io::ignore_io_error { fs::readdir(p) }; for path in files.iter() { if path.extension_str() == Some(os::consts::DLL_EXTENSION) { let stuff : &str = path.filestem_str().expect("has_library: weird path"); diff --git a/src/librustpkg/lib.rs b/src/librustpkg/lib.rs index cc10f15ffb1..d69c8db52c6 100644 --- a/src/librustpkg/lib.rs +++ b/src/librustpkg/lib.rs @@ -27,8 +27,7 @@ extern mod syntax; use std::{os, result, run, str, task}; use std::hashmap::HashSet; use std::rt::io; -use std::rt::io::file; -use std::rt::io::File; +use std::rt::io::fs; pub use std::path::Path; use extra::workcache; @@ -545,7 +544,7 @@ impl CtxMethods for BuildContext { note(format!("Cleaning package {} (removing directory {})", id.to_str(), dir.display())); if dir.exists() { - file::rmdir_recursive(&dir); + fs::rmdir_recursive(&dir); note(format!("Removed directory {}", dir.display())); } @@ -661,8 +660,8 @@ impl CtxMethods for BuildContext { for exec in subex.iter() { debug!("Copying: {} -> {}", exec.display(), sub_target_ex.display()); - file::mkdir_recursive(&sub_target_ex.dir_path(), io::UserRWX); - File::copy(exec, &sub_target_ex); + fs::mkdir_recursive(&sub_target_ex.dir_path(), io::UserRWX); + fs::copy(exec, &sub_target_ex); // FIXME (#9639): This needs to handle non-utf8 paths exe_thing.discover_output("binary", sub_target_ex.as_str().unwrap(), @@ -674,8 +673,8 @@ impl CtxMethods for BuildContext { .clone().expect(format!("I built {} but apparently \ didn't install it!", lib.display())); target_lib.set_filename(lib.filename().expect("weird target lib")); - file::mkdir_recursive(&target_lib.dir_path(), io::UserRWX); - File::copy(lib, &target_lib); + fs::mkdir_recursive(&target_lib.dir_path(), io::UserRWX); + fs::copy(lib, &target_lib); debug!("3. discovering output {}", target_lib.display()); exe_thing.discover_output("binary", target_lib.as_str().unwrap(), @@ -708,10 +707,10 @@ impl CtxMethods for BuildContext { } fn init(&self) { - file::mkdir_recursive(&Path::new("src"), io::UserRWX); - file::mkdir_recursive(&Path::new("bin"), io::UserRWX); - file::mkdir_recursive(&Path::new("lib"), io::UserRWX); - file::mkdir_recursive(&Path::new("build"), io::UserRWX); + fs::mkdir_recursive(&Path::new("src"), io::UserRWX); + fs::mkdir_recursive(&Path::new("bin"), io::UserRWX); + fs::mkdir_recursive(&Path::new("lib"), io::UserRWX); + fs::mkdir_recursive(&Path::new("build"), io::UserRWX); } fn uninstall(&self, _id: &str, _vers: Option<~str>) { diff --git a/src/librustpkg/package_source.rs b/src/librustpkg/package_source.rs index 5e3a90bbf58..3023f3ed60c 100644 --- a/src/librustpkg/package_source.rs +++ b/src/librustpkg/package_source.rs @@ -13,8 +13,7 @@ extern mod extra; use target::*; use package_id::PkgId; use std::rt::io; -use std::rt::io::file; -use std::rt::io::File; +use std::rt::io::fs; use std::os; use context::*; use crate::Crate; @@ -302,7 +301,7 @@ impl PkgSrc { // Move clone_target to local. // First, create all ancestor directories. let moved = make_dir_rwx_recursive(&local.dir_path()) - && io::result(|| File::rename(&clone_target, local)).is_ok(); + && io::result(|| fs::rename(&clone_target, local)).is_ok(); if moved { Some(local.clone()) } else { None } } @@ -351,7 +350,7 @@ impl PkgSrc { let prefix = self.start_dir.component_iter().len(); debug!("Matching against {}", self.id.short_name); - for pth in file::walk_dir(&self.start_dir) { + for pth in fs::walk_dir(&self.start_dir) { let maybe_known_crate_set = match pth.filename_str() { Some(filename) if filter(filename) => match filename { "lib.rs" => Some(&mut self.libs), diff --git a/src/librustpkg/path_util.rs b/src/librustpkg/path_util.rs index e8f1b2300c7..949efacaa11 100644 --- a/src/librustpkg/path_util.rs +++ b/src/librustpkg/path_util.rs @@ -20,8 +20,7 @@ use std::libc; use std::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR}; use std::os; use std::rt::io; -use std::rt::io::file; -use std::rt::io::File; +use std::rt::io::fs; use messages::*; pub fn default_workspace() -> Path { @@ -31,7 +30,7 @@ pub fn default_workspace() -> Path { } let result = p[0]; if !result.is_dir() { - file::mkdir_recursive(&result, io::UserRWX); + fs::mkdir_recursive(&result, io::UserRWX); } result } @@ -46,11 +45,11 @@ pub static U_RWX: i32 = (S_IRUSR | S_IWUSR | S_IXUSR) as i32; /// and executable by the user. Returns true iff creation /// succeeded. pub fn make_dir_rwx(p: &Path) -> bool { - io::result(|| file::mkdir(p, io::UserRWX)).is_ok() + io::result(|| fs::mkdir(p, io::UserRWX)).is_ok() } pub fn make_dir_rwx_recursive(p: &Path) -> bool { - io::result(|| file::mkdir_recursive(p, io::UserRWX)).is_ok() + io::result(|| fs::mkdir_recursive(p, io::UserRWX)).is_ok() } // n.b. The next three functions ignore the package version right @@ -73,7 +72,7 @@ pub fn workspace_contains_package_id_(pkgid: &PkgId, workspace: &Path, if !src_dir.is_dir() { return None } let mut found = None; - for p in file::walk_dir(&src_dir) { + for p in fs::walk_dir(&src_dir) { if p.is_dir() { if p == src_dir.join(&pkgid.path) || { let pf = p.filename_str(); @@ -216,7 +215,7 @@ pub fn system_library(sysroot: &Path, lib_name: &str) -> Option<Path> { fn library_in(short_name: &str, version: &Version, dir_to_search: &Path) -> Option<Path> { debug!("Listing directory {}", dir_to_search.display()); - let dir_contents = do io::ignore_io_error { file::readdir(dir_to_search) }; + let dir_contents = do io::ignore_io_error { fs::readdir(dir_to_search) }; debug!("dir has {:?} entries", dir_contents.len()); let lib_prefix = format!("{}{}", os::consts::DLL_PREFIX, short_name); @@ -339,7 +338,7 @@ fn target_file_in_workspace(pkgid: &PkgId, workspace: &Path, (Install, Lib) => target_lib_dir(workspace), (Install, _) => target_bin_dir(workspace) }; - if io::result(|| file::mkdir_recursive(&result, io::UserRWX)).is_err() { + if io::result(|| fs::mkdir_recursive(&result, io::UserRWX)).is_err() { cond.raise((result.clone(), format!("target_file_in_workspace couldn't \ create the {} dir (pkgid={}, workspace={}, what={:?}, where={:?}", subdir, pkgid.to_str(), workspace.display(), what, where))); @@ -354,7 +353,7 @@ pub fn build_pkg_id_in_workspace(pkgid: &PkgId, workspace: &Path) -> Path { result.push(&pkgid.path); debug!("Creating build dir {} for package id {}", result.display(), pkgid.to_str()); - file::mkdir_recursive(&result, io::UserRWX); + fs::mkdir_recursive(&result, io::UserRWX); return result; } @@ -399,12 +398,12 @@ pub fn uninstall_package_from(workspace: &Path, pkgid: &PkgId) { let mut did_something = false; let installed_bin = target_executable_in_workspace(pkgid, workspace); if installed_bin.exists() { - File::unlink(&installed_bin); + fs::unlink(&installed_bin); did_something = true; } let installed_lib = target_library_in_workspace(pkgid, workspace); if installed_lib.exists() { - File::unlink(&installed_lib); + fs::unlink(&installed_lib); did_something = true; } if !did_something { diff --git a/src/librustpkg/source_control.rs b/src/librustpkg/source_control.rs index e5d1c9b597f..bcda3168bd8 100644 --- a/src/librustpkg/source_control.rs +++ b/src/librustpkg/source_control.rs @@ -12,7 +12,7 @@ use std::{run, str}; use std::run::{ProcessOutput, ProcessOptions, Process}; -use std::rt::io::file; +use std::rt::io::fs; use extra::tempfile::TempDir; use version::*; use path_util::chmod_read_only; @@ -96,7 +96,7 @@ pub enum CloneResult { pub fn make_read_only(target: &Path) { // Now, make all the files in the target dir read-only - for p in file::walk_dir(target) { + for p in fs::walk_dir(target) { if !p.is_dir() { assert!(chmod_read_only(&p)); } diff --git a/src/librustpkg/tests.rs b/src/librustpkg/tests.rs index a2ef80db6d6..fc46346a35e 100644 --- a/src/librustpkg/tests.rs +++ b/src/librustpkg/tests.rs @@ -13,7 +13,7 @@ use context::{BuildContext, Context, RustcFlags}; use std::{os, run, str, task}; use std::rt::io; -use std::rt::io::file; +use std::rt::io::fs; use std::rt::io::File; use extra::arc::Arc; use extra::arc::RWArc; @@ -92,7 +92,7 @@ fn writeFile(file_path: &Path, contents: &str) { fn mk_emptier_workspace(tag: &str) -> TempDir { let workspace = TempDir::new(tag).expect("couldn't create temp dir"); let package_dir = workspace.path().join("src"); - file::mkdir_recursive(&package_dir, io::UserRWX); + fs::mkdir_recursive(&package_dir, io::UserRWX); workspace } @@ -107,7 +107,7 @@ fn mk_workspace(workspace: &Path, short_name: &Path, version: &Version) -> Path // FIXME (#9639): This needs to handle non-utf8 paths let package_dir = workspace.join_many([~"src", format!("{}-{}", short_name.as_str().unwrap(), version.to_str())]); - file::mkdir_recursive(&package_dir, io::UserRWX); + fs::mkdir_recursive(&package_dir, io::UserRWX); package_dir } @@ -123,7 +123,7 @@ fn mk_temp_workspace(short_name: &Path, version: &Version) -> (TempDir, Path) { package_dir.is_dir()); // Create main, lib, test, and bench files debug!("mk_workspace: creating {}", package_dir.display()); - file::mkdir_recursive(&package_dir, io::UserRWX); + fs::mkdir_recursive(&package_dir, io::UserRWX); debug!("Created {} and does it exist? {:?}", package_dir.display(), package_dir.is_dir()); // Create main, lib, test, and bench files @@ -162,7 +162,7 @@ fn init_git_repo(p: &Path) -> TempDir { let tmp = TempDir::new("git_local").expect("couldn't create temp dir"); let work_dir = tmp.path().join(p); let work_dir_for_opts = work_dir.clone(); - file::mkdir_recursive(&work_dir, io::UserRWX); + fs::mkdir_recursive(&work_dir, io::UserRWX); debug!("Running: git init in {}", work_dir.display()); run_git([~"init"], None, &work_dir_for_opts, format!("Couldn't initialize git repository in {}", work_dir.display())); @@ -311,7 +311,7 @@ fn create_local_package_in(pkgid: &PkgId, pkgdir: &Path) -> Path { let package_dir = pkgdir.join_many([~"src", pkgid.to_str()]); // Create main, lib, test, and bench files - file::mkdir_recursive(&package_dir, io::UserRWX); + fs::mkdir_recursive(&package_dir, io::UserRWX); debug!("Created {} and does it exist? {:?}", package_dir.display(), package_dir.is_dir()); // Create main, lib, test, and bench files @@ -389,7 +389,7 @@ fn test_executable_exists(repo: &Path, short_name: &str) -> bool { fn remove_executable_file(p: &PkgId, workspace: &Path) { let exec = target_executable_in_workspace(&PkgId::new(p.short_name), workspace); if exec.exists() { - File::unlink(&exec); + fs::unlink(&exec); } } @@ -410,7 +410,7 @@ fn built_executable_exists(repo: &Path, short_name: &str) -> bool { fn remove_built_executable_file(p: &PkgId, workspace: &Path) { let exec = built_executable_in_workspace(&PkgId::new(p.short_name), workspace); match exec { - Some(r) => File::unlink(&r), + Some(r) => fs::unlink(&r), None => () } } @@ -495,7 +495,7 @@ fn output_file_name(workspace: &Path, short_name: ~str) -> Path { fn touch_source_file(workspace: &Path, pkgid: &PkgId) { use conditions::bad_path::cond; let pkg_src_dir = workspace.join_many([~"src", pkgid.to_str()]); - let contents = file::readdir(&pkg_src_dir); + let contents = fs::readdir(&pkg_src_dir); for p in contents.iter() { if p.extension_str() == Some("rs") { // should be able to do this w/o a process @@ -514,7 +514,7 @@ fn touch_source_file(workspace: &Path, pkgid: &PkgId) { fn touch_source_file(workspace: &Path, pkgid: &PkgId) { use conditions::bad_path::cond; let pkg_src_dir = workspace.join_many([~"src", pkgid.to_str()]); - let contents = file::readdir(&pkg_src_dir); + let contents = fs::readdir(&pkg_src_dir); for p in contents.iter() { if p.extension_str() == Some("rs") { // should be able to do this w/o a process @@ -558,13 +558,13 @@ fn test_make_dir_rwx() { let temp = &os::tmpdir(); let dir = temp.join("quux"); if dir.exists() { - file::rmdir_recursive(&dir); + fs::rmdir_recursive(&dir); } debug!("Trying to make {}", dir.display()); assert!(make_dir_rwx(&dir)); assert!(dir.is_dir()); assert!(is_rwx(&dir)); - file::rmdir_recursive(&dir); + fs::rmdir_recursive(&dir); } // n.b. I ignored the next two tests for now because something funny happens on linux @@ -771,7 +771,7 @@ fn test_package_version() { let repo = repo.path(); let repo_subdir = repo.join_many(["mockgithub.com", "catamorphism", "test_pkg_version"]); debug!("Writing files in: {}", repo_subdir.display()); - file::mkdir_recursive(&repo_subdir, io::UserRWX); + fs::mkdir_recursive(&repo_subdir, io::UserRWX); writeFile(&repo_subdir.join("main.rs"), "fn main() { let _x = (); }"); writeFile(&repo_subdir.join("lib.rs"), @@ -893,7 +893,7 @@ fn package_script_with_default_build() { let source = Path::new(file!()).dir_path().join_many( [~"testsuite", ~"pass", ~"src", ~"fancy-lib", ~"pkg.rs"]); debug!("package_script_with_default_build: {}", source.display()); - File::copy(&source, &dir.join_many(["src", "fancy-lib-0.1", "pkg.rs"])); + fs::copy(&source, &dir.join_many(["src", "fancy-lib-0.1", "pkg.rs"])); command_line_test([~"install", ~"fancy-lib"], dir); assert_lib_exists(dir, &Path::new("fancy-lib"), NoVersion); assert!(target_build_dir(dir).join_many([~"fancy-lib", ~"generated.rs"]).exists()); @@ -907,7 +907,7 @@ fn rustpkg_build_no_arg() { let tmp = TempDir::new("rustpkg_build_no_arg").expect("rustpkg_build_no_arg failed"); let tmp = tmp.path().join(".rust"); let package_dir = tmp.join_many(["src", "foo"]); - file::mkdir_recursive(&package_dir, io::UserRWX); + fs::mkdir_recursive(&package_dir, io::UserRWX); writeFile(&package_dir.join("main.rs"), "fn main() { let _x = (); }"); @@ -921,7 +921,7 @@ fn rustpkg_install_no_arg() { let tmp = TempDir::new("rustpkg_install_no_arg").expect("rustpkg_install_no_arg failed"); let tmp = tmp.path().join(".rust"); let package_dir = tmp.join_many(["src", "foo"]); - file::mkdir_recursive(&package_dir, io::UserRWX); + fs::mkdir_recursive(&package_dir, io::UserRWX); writeFile(&package_dir.join("lib.rs"), "fn main() { let _x = (); }"); debug!("install_no_arg: dir = {}", package_dir.display()); @@ -934,7 +934,7 @@ fn rustpkg_clean_no_arg() { let tmp = TempDir::new("rustpkg_clean_no_arg").expect("rustpkg_clean_no_arg failed"); let tmp = tmp.path().join(".rust"); let package_dir = tmp.join_many(["src", "foo"]); - file::mkdir_recursive(&package_dir, io::UserRWX); + fs::mkdir_recursive(&package_dir, io::UserRWX); writeFile(&package_dir.join("main.rs"), "fn main() { let _x = (); }"); @@ -969,9 +969,9 @@ fn rust_path_test() { fn rust_path_contents() { let dir = TempDir::new("rust_path").expect("rust_path_contents failed"); let abc = &dir.path().join_many(["A", "B", "C"]); - file::mkdir_recursive(&abc.join(".rust"), io::UserRWX); - file::mkdir_recursive(&abc.with_filename(".rust"), io::UserRWX); - file::mkdir_recursive(&abc.dir_path().with_filename(".rust"), io::UserRWX); + fs::mkdir_recursive(&abc.join(".rust"), io::UserRWX); + fs::mkdir_recursive(&abc.with_filename(".rust"), io::UserRWX); + fs::mkdir_recursive(&abc.dir_path().with_filename(".rust"), io::UserRWX); assert!(os::change_dir(abc)); let p = rust_path(); @@ -1223,7 +1223,7 @@ fn test_extern_mod() { let lib_depend_dir = TempDir::new("foo").expect("test_extern_mod"); let lib_depend_dir = lib_depend_dir.path(); let aux_dir = lib_depend_dir.join_many(["src", "mockgithub.com", "catamorphism", "test_pkg"]); - file::mkdir_recursive(&aux_dir, io::UserRWX); + fs::mkdir_recursive(&aux_dir, io::UserRWX); let aux_pkg_file = aux_dir.join("lib.rs"); writeFile(&aux_pkg_file, "pub mod bar { pub fn assert_true() { assert!(true); } }\n"); @@ -1272,7 +1272,7 @@ fn test_extern_mod_simpler() { let lib_depend_dir = TempDir::new("foo").expect("test_extern_mod_simpler"); let lib_depend_dir = lib_depend_dir.path(); let aux_dir = lib_depend_dir.join_many(["src", "rust-awesomeness"]); - file::mkdir_recursive(&aux_dir, io::UserRWX); + fs::mkdir_recursive(&aux_dir, io::UserRWX); let aux_pkg_file = aux_dir.join("lib.rs"); writeFile(&aux_pkg_file, "pub mod bar { pub fn assert_true() { assert!(true); } }\n"); @@ -1422,7 +1422,7 @@ fn rust_path_hack_cwd() { // Same as rust_path_hack_test, but the CWD is the dir to build out of let cwd = TempDir::new("foo").expect("rust_path_hack_cwd"); let cwd = cwd.path().join("foo"); - file::mkdir_recursive(&cwd, io::UserRWX); + fs::mkdir_recursive(&cwd, io::UserRWX); writeFile(&cwd.join("lib.rs"), "pub fn f() { }"); let dest_workspace = mk_empty_workspace(&Path::new("bar"), &NoVersion, "dest_workspace"); @@ -1442,7 +1442,7 @@ fn rust_path_hack_multi_path() { // Same as rust_path_hack_test, but with a more complex package ID let cwd = TempDir::new("pkg_files").expect("rust_path_hack_cwd"); let subdir = cwd.path().join_many(["foo", "bar", "quux"]); - file::mkdir_recursive(&subdir, io::UserRWX); + fs::mkdir_recursive(&subdir, io::UserRWX); writeFile(&subdir.join("lib.rs"), "pub fn f() { }"); let name = ~"foo/bar/quux"; @@ -1856,7 +1856,7 @@ fn pkgid_pointing_to_subdir() { // rustpkg should recognize that and treat the part after some_repo/ as a subdir let workspace = TempDir::new("parent_repo").expect("Couldn't create temp dir"); let workspace = workspace.path(); - file::mkdir_recursive(&workspace.join_many(["src", "mockgithub.com", + fs::mkdir_recursive(&workspace.join_many(["src", "mockgithub.com", "mozilla", "some_repo"]), io::UserRWX); @@ -1864,14 +1864,14 @@ fn pkgid_pointing_to_subdir() { "extras", "foo"]); let bar_dir = workspace.join_many(["src", "mockgithub.com", "mozilla", "some_repo", "extras", "bar"]); - file::mkdir_recursive(&foo_dir, io::UserRWX); - file::mkdir_recursive(&bar_dir, io::UserRWX); + fs::mkdir_recursive(&foo_dir, io::UserRWX); + fs::mkdir_recursive(&bar_dir, io::UserRWX); writeFile(&foo_dir.join("lib.rs"), "pub fn f() {}"); writeFile(&bar_dir.join("lib.rs"), "pub fn g() {}"); debug!("Creating a file in {}", workspace.display()); let testpkg_dir = workspace.join_many(["src", "testpkg-0.1"]); - file::mkdir_recursive(&testpkg_dir, io::UserRWX); + fs::mkdir_recursive(&testpkg_dir, io::UserRWX); writeFile(&testpkg_dir.join("main.rs"), "extern mod foo = \"mockgithub.com/mozilla/some_repo/extras/foo\";\n @@ -1946,7 +1946,7 @@ fn test_target_specific_build_dir() { workspace); assert!(target_build_dir(workspace).is_dir()); assert!(built_executable_exists(workspace, "foo")); - assert!(file::readdir(&workspace.join("build")).len() == 1); + assert!(fs::readdir(&workspace.join("build")).len() == 1); } #[test] @@ -1962,7 +1962,7 @@ fn test_target_specific_install_dir() { workspace); assert!(workspace.join_many([~"lib", host_triple()]).is_dir()); assert_lib_exists(workspace, &Path::new("foo"), NoVersion); - assert!(file::readdir(&workspace.join("lib")).len() == 1); + assert!(fs::readdir(&workspace.join("lib")).len() == 1); assert!(workspace.join("bin").is_dir()); assert_executable_exists(workspace, "foo"); } @@ -1975,7 +1975,7 @@ fn test_dependencies_terminate() { let workspace = workspace.path(); let b_dir = workspace.join_many(["src", "b-0.1"]); let b_subdir = b_dir.join("test"); - file::mkdir_recursive(&b_subdir, io::UserRWX); + fs::mkdir_recursive(&b_subdir, io::UserRWX); writeFile(&b_subdir.join("test.rs"), "extern mod b; use b::f; #[test] fn g() { f() }"); command_line_test([~"install", ~"b"], workspace); @@ -2173,7 +2173,7 @@ fn test_installed_local_changes() { debug!("repo = {}", repo.display()); let repo_subdir = repo.join_many(["mockgithub.com", "catamorphism", "test-pkg"]); debug!("repo_subdir = {}", repo_subdir.display()); - file::mkdir_recursive(&repo.join_many([".rust", "src"]), io::UserRWX); + fs::mkdir_recursive(&repo.join_many([".rust", "src"]), io::UserRWX); writeFile(&repo_subdir.join("main.rs"), "fn main() { let _x = (); }"); @@ -2256,7 +2256,7 @@ fn find_sources_in_cwd() { let temp_dir = TempDir::new("sources").expect("find_sources_in_cwd failed"); let temp_dir = temp_dir.path(); let source_dir = temp_dir.join("foo"); - file::mkdir_recursive(&source_dir, io::UserRWX); + fs::mkdir_recursive(&source_dir, io::UserRWX); writeFile(&source_dir.join("main.rs"), "fn main() { let _x = (); }"); command_line_test([~"install", ~"foo"], &source_dir); @@ -2279,7 +2279,7 @@ fn test_c_dependency_ok() { debug!("dir = {}", dir.display()); let source = Path::new(file!()).dir_path().join_many( [~"testsuite", ~"pass", ~"src", ~"c-dependencies", ~"pkg.rs"]); - File::copy(&source, &dir.join_many([~"src", ~"cdep-0.1", ~"pkg.rs"])); + fs::copy(&source, &dir.join_many([~"src", ~"cdep-0.1", ~"pkg.rs"])); command_line_test([~"build", ~"cdep"], dir); assert_executable_exists(dir, "cdep"); let out_dir = target_build_dir(dir).join("cdep"); @@ -2300,7 +2300,7 @@ fn test_c_dependency_no_rebuilding() { debug!("dir = {}", dir.display()); let source = Path::new(file!()).dir_path().join_many( [~"testsuite", ~"pass", ~"src", ~"c-dependencies", ~"pkg.rs"]); - File::copy(&source, &dir.join_many([~"src", ~"cdep-0.1", ~"pkg.rs"])); + fs::copy(&source, &dir.join_many([~"src", ~"cdep-0.1", ~"pkg.rs"])); command_line_test([~"build", ~"cdep"], dir); assert_executable_exists(dir, "cdep"); let out_dir = target_build_dir(dir).join("cdep"); @@ -2333,7 +2333,7 @@ fn test_c_dependency_yes_rebuilding() { [~"testsuite", ~"pass", ~"src", ~"c-dependencies", ~"pkg.rs"]); let target = dir.join_many([~"src", ~"cdep-0.1", ~"pkg.rs"]); debug!("Copying {} -> {}", source.display(), target.display()); - File::copy(&source, &target); + fs::copy(&source, &target); command_line_test([~"build", ~"cdep"], dir); assert_executable_exists(dir, "cdep"); let out_dir = target_build_dir(dir).join("cdep"); @@ -2357,5 +2357,5 @@ fn test_c_dependency_yes_rebuilding() { /// Returns true if p exists and is executable fn is_executable(p: &Path) -> bool { - p.exists() && p.stat().perm & io::UserExec == io::UserExec + p.exists() && p.stat().perm & io::UserExecute == io::UserExecute } diff --git a/src/librustpkg/testsuite/pass/src/c-dependencies/foo.rs b/src/librustpkg/testsuite/pass/src/c-dependencies/foo.rs index 542a6af402d..3b233c9f6a8 100644 --- a/src/librustpkg/testsuite/pass/src/c-dependencies/foo.rs +++ b/src/librustpkg/testsuite/pass/src/c-dependencies/foo.rs @@ -9,4 +9,4 @@ // except according to those terms. pub fn do_nothing() { -} \ No newline at end of file +} diff --git a/src/librustpkg/util.rs b/src/librustpkg/util.rs index d0ba5ce368f..ec7771c2ab5 100644 --- a/src/librustpkg/util.rs +++ b/src/librustpkg/util.rs @@ -11,7 +11,7 @@ use std::libc; use std::os; use std::rt::io; -use std::rt::io::file; +use std::rt::io::fs; use extra::workcache; use rustc::driver::{driver, session}; use extra::getopts::groups::getopts; @@ -185,7 +185,7 @@ pub fn compile_input(context: &BuildContext, let mut out_dir = target_build_dir(workspace); out_dir.push(&pkg_id.path); // Make the output directory if it doesn't exist already - file::mkdir_recursive(&out_dir, io::UserRWX); + fs::mkdir_recursive(&out_dir, io::UserRWX); let binary = os::args()[0].to_managed(); @@ -261,7 +261,7 @@ pub fn compile_input(context: &BuildContext, assert!(p.is_dir()) } else { - file::mkdir_recursive(p, io::UserRWX); + fs::mkdir_recursive(p, io::UserRWX); } } diff --git a/src/librustuv/file.rs b/src/librustuv/file.rs index 99060de1d2d..8c9302e1238 100644 --- a/src/librustuv/file.rs +++ b/src/librustuv/file.rs @@ -257,6 +257,7 @@ impl FsRequest { uvll::uv_fs_symlink(loop_.native_handle(), self.native_handle(), src.with_ref(|p| p), dst.with_ref(|p| p), + 0, complete_cb_ptr) }, 0); } diff --git a/src/librustuv/uvio.rs b/src/librustuv/uvio.rs index 25839c429da..15d5fe702a5 100644 --- a/src/librustuv/uvio.rs +++ b/src/librustuv/uvio.rs @@ -464,16 +464,18 @@ fn fs_mkstat(f: &mut FsRequest) -> FileStat { created: to_msec(stat.st_birthtim), modified: to_msec(stat.st_mtim), accessed: to_msec(stat.st_atim), - device: stat.st_dev as u64, - inode: stat.st_ino as u64, - rdev: stat.st_rdev as u64, - nlink: stat.st_nlink as u64, - uid: stat.st_uid as u64, - gid: stat.st_gid as u64, - blksize: stat.st_blksize as u64, - blocks: stat.st_blocks as u64, - flags: stat.st_flags as u64, - gen: stat.st_gen as u64, + unstable: io::UnstableFileStat { + device: stat.st_dev as u64, + inode: stat.st_ino as u64, + rdev: stat.st_rdev as u64, + nlink: stat.st_nlink as u64, + uid: stat.st_uid as u64, + gid: stat.st_gid as u64, + blksize: stat.st_blksize as u64, + blocks: stat.st_blocks as u64, + flags: stat.st_flags as u64, + gen: stat.st_gen as u64, + } } } @@ -764,7 +766,7 @@ impl IoFactory for UvIoFactory { } fn fs_readlink(&mut self, path: &CString) -> Result<Path, IoError> { fn getlink(f: &mut FsRequest) -> Path { - Path::new(unsafe { CString::new(f.get_path(), false) }) + Path::new(unsafe { CString::new(f.get_ptr() as *libc::c_char, false) }) } do uv_fs_helper(self.uv_loop(), getlink) |req, l, cb| { req.readlink(l, path, cb) diff --git a/src/librustuv/uvll.rs b/src/librustuv/uvll.rs index b8f16db1066..2d850383766 100644 --- a/src/librustuv/uvll.rs +++ b/src/librustuv/uvll.rs @@ -1207,7 +1207,7 @@ externfn!(fn uv_fs_ftruncate(handle: *uv_loop_t, req: *uv_fs_t, file: c_int, externfn!(fn uv_fs_readlink(handle: *uv_loop_t, req: *uv_fs_t, file: *c_char, cb: *u8) -> c_int) externfn!(fn uv_fs_symlink(handle: *uv_loop_t, req: *uv_fs_t, src: *c_char, - dst: *c_char, cb: *u8) -> c_int) + dst: *c_char, flags: c_int, cb: *u8) -> c_int) externfn!(fn uv_fs_link(handle: *uv_loop_t, req: *uv_fs_t, src: *c_char, dst: *c_char, cb: *u8) -> c_int) externfn!(fn uv_fs_chown(handle: *uv_loop_t, req: *uv_fs_t, src: *c_char, diff --git a/src/libstd/os.rs b/src/libstd/os.rs index f461781e132..b066685f6ef 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -42,7 +42,6 @@ use ptr; use str; use to_str; use unstable::finally::Finally; -use vec; pub use os::consts::*; @@ -382,6 +381,7 @@ pub fn self_exe_path() -> Option<Path> { unsafe { use libc::funcs::bsd44::*; use libc::consts::os::extra::*; + use vec; let mib = ~[CTL_KERN as c_int, KERN_PROC as c_int, KERN_PROC_PATHNAME as c_int, -1 as c_int]; @@ -405,23 +405,11 @@ pub fn self_exe_path() -> Option<Path> { #[cfg(target_os = "linux")] #[cfg(target_os = "android")] fn load_self() -> Option<~[u8]> { - #[fixed_stack_segment]; #[inline(never)]; - unsafe { - use libc::funcs::posix01::unistd::readlink; - - let mut path: ~[u8] = vec::with_capacity(TMPBUF_SZ); + use std::rt::io; - let len = do path.as_mut_buf |buf, _| { - do "/proc/self/exe".with_c_str |proc_self_buf| { - readlink(proc_self_buf, buf as *mut c_char, TMPBUF_SZ as size_t) as uint - } - }; - if len == -1 { - None - } else { - vec::raw::set_len(&mut path, len as uint); - Some(path) - } + match io::result(|| io::fs::readlink(&Path::new("/proc/self/exe"))) { + Ok(Some(path)) => Some(path.as_vec().to_owned()), + Ok(None) | Err(*) => None } } @@ -430,6 +418,7 @@ pub fn self_exe_path() -> Option<Path> { #[fixed_stack_segment]; #[inline(never)]; unsafe { use libc::funcs::extra::_NSGetExecutablePath; + use vec; let mut sz: u32 = 0; _NSGetExecutablePath(ptr::mut_null(), &mut sz); if sz == 0 { return None; } @@ -814,6 +803,7 @@ fn real_args() -> ~[~str] { #[cfg(windows)] fn real_args() -> ~[~str] { #[fixed_stack_segment]; #[inline(never)]; + use vec; let mut nArgs: c_int = 0; let lpArgCount: *mut c_int = &mut nArgs; @@ -1495,7 +1485,8 @@ mod tests { use result::{Ok, Err}; use os::*; use libc::*; - use rt::io::File; + use rt::io; + use rt::io::fs; #[cfg(unix)] #[fixed_stack_segment] @@ -1544,7 +1535,7 @@ mod tests { assert!(*chunk.data == 0xbe); close(fd); } - File::unlink(&path); + do io::ignore_io_error { fs::unlink(&path); } } // More recursive_mkdir tests are in extra::tempfile diff --git a/src/libstd/rt/io/file.rs b/src/libstd/rt/io/fs.rs index c3f5f387211..22d7ea55f3b 100644 --- a/src/libstd/rt/io/file.rs +++ b/src/libstd/rt/io/fs.rs @@ -25,6 +25,24 @@ defined in `std::path::Path`. The impl adds useful methods about inspecting the metadata of a file. This includes getting the `stat` information, reading off particular bits of it, etc. +# Example + + use std::rt::io::{File, fs}; + + let path = Path::new("foo.txt"); + + // create the file, whether it exists or not + let mut file = File::create(&path); + file.write(bytes!("foobar")); + + // open the file in read-only mode + let mut file = File::open(&path); + file.read_to_end(); + + println!("{}", path.stat().size); + fs::symlink(&path, &Path::new("bar.txt")); + fs::unlink(&path); + */ use c_str::ToCStr; @@ -42,16 +60,14 @@ use vec::OwnedVector; /// Unconstrained file access type that exposes read and write operations /// -/// Can be retreived via `File::open()` and `Path.File::open_mode()`. +/// Can be constructed via `File::open()`, `File::create()`, and +/// `File::open_mode()`. /// /// # Errors /// /// This type will raise an io_error condition if operations are attempted against /// it for which its underlying file descriptor was not configured at creation -/// time, via the `FileAccess` parameter to `file::open()`. -/// -/// For this reason, it is best to use the access-constrained wrappers that are -/// exposed via `Path.open()` and `Path.create()`. +/// time, via the `FileAccess` parameter to `File::open_mode()`. pub struct File { priv fd: ~RtioFileStream, priv path: Path, @@ -140,7 +156,7 @@ impl File { /// /// use std::rt::io::File; /// - /// let contents = File::open("foo.txt").read_to_end(); + /// let contents = File::open(&Path::new("foo.txt")).read_to_end(); pub fn open(path: &Path) -> Option<File> { File::open_mode(path, Open, Read) } @@ -155,239 +171,12 @@ impl File { /// /// use std::rt::io::File; /// - /// File::create("foo.txt").write(bytes!("This is a sample file")); + /// let mut f = File::create(&Path::new("foo.txt")); + /// f.write(bytes!("This is a sample file")); pub fn create(path: &Path) -> Option<File> { File::open_mode(path, Truncate, Write) } - /// Unlink a file from the underlying filesystem. - /// - /// # Example - /// - /// use std::rt::io::File; - /// - /// let p = Path::new("/some/file/path.txt"); - /// File::unlink(&p); - /// // if we made it here without failing, then the - /// // unlink operation was successful - /// - /// Note that, just because an unlink call was successful, it is not - /// guaranteed that a file is immediately deleted (e.g. depending on - /// platform, other open file descriptors may prevent immediate removal) - /// - /// # Errors - /// - /// This function will raise an `io_error` condition if the path points to a - /// directory, the user lacks permissions to remove the file, or if some - /// other filesystem-level error occurs. - pub fn unlink(path: &Path) { - do io_raise |io| { io.fs_unlink(&path.to_c_str()) }; - } - - /// Given a path, query the file system to get information about a file, - /// directory, etc. This function will traverse symlinks to query - /// information about the destination file. - /// - /// Returns a fully-filled out stat structure on succes, and on failure it - /// will return a dummy stat structure (it is expected that the condition - /// raised is handled as well). - /// - /// # Example - /// - /// use std::rt::io::{File, io_error}; - /// - /// let p = Path::new("/some/file/path.txt"); - /// - /// do io_error::cond.trap(|_| { - /// // hoo-boy... - /// }).inside { - /// let info = File::stat(p); - /// if info.is_file { - /// // just imagine the possibilities ... - /// } - /// } - /// - /// # Errors - /// - /// This call will raise an `io_error` condition if the user lacks the - /// requisite permissions to perform a `stat` call on the given path or if - /// there is no entry in the filesystem at the provided path. - pub fn stat(path: &Path) -> FileStat { - do io_raise |io| { - io.fs_stat(&path.to_c_str()) - }.unwrap_or_else(File::dummystat) - } - - fn dummystat() -> FileStat { - FileStat { - path: Path::new(""), - size: 0, - kind: io::TypeFile, - perm: 0, - created: 0, - modified: 0, - accessed: 0, - device: 0, - inode: 0, - rdev: 0, - nlink: 0, - uid: 0, - gid: 0, - blksize: 0, - blocks: 0, - flags: 0, - gen: 0, - } - } - - /// Perform the same operation as the `stat` function, except that this - /// function does not traverse through symlinks. This will return - /// information about the symlink file instead of the file that it points - /// to. - /// - /// # Errors - /// - /// See `stat` - pub fn lstat(path: &Path) -> FileStat { - do io_raise |io| { - io.fs_lstat(&path.to_c_str()) - }.unwrap_or_else(File::dummystat) - } - - /// Rename a file or directory to a new name. - /// - /// # Example - /// - /// use std::rt::io::File; - /// - /// File::rename(Path::new("foo"), Path::new("bar")); - /// // Oh boy, nothing was raised! - /// - /// # Errors - /// - /// Will raise an `io_error` condition if the provided `path` doesn't exist, - /// the process lacks permissions to view the contents, or if some other - /// intermittent I/O error occurs. - pub fn rename(from: &Path, to: &Path) { - do io_raise |io| { - io.fs_rename(&from.to_c_str(), &to.to_c_str()) - }; - } - - /// Copies the contents of one file to another. This function will also - /// copy the permission bits of the original file to the destination file. - /// - /// Note that if `from` and `to` both point to the same file, then the file - /// will likely get truncated by this operation. - /// - /// # Example - /// - /// use std::rt::io::File; - /// - /// File::copy(Path::new("foo.txt"), Path::new("bar.txt")); - /// // Oh boy, nothing was raised! - /// - /// # Errors - /// - /// Will raise an `io_error` condition is the following situtations, but is - /// not limited to just these cases: - /// - /// * The `from` path is not a file - /// * The `from` file does not exist - /// * The current process does not have the permission rights to access - /// `from` or write `to` - /// - /// Note that this copy is not atomic in that once the destination is - /// ensured to not exist, the is nothing preventing the destination from - /// being created and then destroyed by this operation. - pub fn copy(from: &Path, to: &Path) { - if !from.is_file() { - return io_error::cond.raise(IoError { - kind: io::MismatchedFileTypeForOperation, - desc: "the source path is not an existing file", - detail: None, - }); - } - - let mut reader = match File::open(from) { Some(f) => f, None => return }; - let mut writer = match File::create(to) { Some(f) => f, None => return }; - let mut buf = [0, ..io::DEFAULT_BUF_SIZE]; - - loop { - match reader.read(buf) { - Some(amt) => writer.write(buf.slice_to(amt)), - None => break - } - } - - File::chmod(to, from.stat().perm) - } - - /// Changes the permission mode bits found on a file or a directory. This - /// function takes a mask from the `io` module - /// - /// # Example - /// - /// use std::rt::io; - /// use std::rt::io::File; - /// - /// File::chmod(&Path::new("file.txt"), io::UserFile); - /// File::chmod(&Path::new("file.txt"), io::UserRead | io::UserWrite); - /// File::chmod(&Path::new("dir"), io::UserDir); - /// File::chmod(&Path::new("file.exe"), io::UserExec); - /// - /// # Errors - /// - /// If this funciton encounters an I/O error, it will raise on the `io_error` - /// condition. Some possible error situations are not having the permission to - /// change the attributes of a file or the file not existing. - pub fn chmod(path: &Path, mode: io::FilePermission) { - do io_raise |io| { - io.fs_chmod(&path.to_c_str(), mode) - }; - } - - /// Change the user and group owners of a file at the specified path. - /// - /// # Errors - /// - /// This funtion will raise on the `io_error` condition on failure. - pub fn chown(path: &Path, uid: int, gid: int) { - do io_raise |io| { io.fs_chown(&path.to_c_str(), uid, gid) }; - } - - /// Creates a new hard link on the filesystem. The `dst` path will be a - /// link pointing to the `src` path. Note that systems often require these - /// two paths to both be located on the same filesystem. - /// - /// # Errors - /// - /// This function will raise on the `io_error` condition on failure. - pub fn link(src: &Path, dst: &Path) { - do io_raise |io| { io.fs_link(&src.to_c_str(), &dst.to_c_str()) }; - } - - /// Creates a new symbolic link on the filesystem. The `dst` path will be a - /// symlink pointing to the `src` path. - /// - /// # Errors - /// - /// This function will raise on the `io_error` condition on failure. - pub fn symlink(src: &Path, dst: &Path) { - do io_raise |io| { io.fs_symlink(&src.to_c_str(), &dst.to_c_str()) }; - } - - /// Reads a symlink, returning the file that the symlink points to. - /// - /// # Errors - /// - /// This function will raise on the `io_error` condition on failure. - /// - /// XXX: does this fail if called on files. - pub fn readlink(path: &Path) -> Option<Path> { - do io_raise |io| { io.fs_readlink(&path.to_c_str()) } - } - /// Returns the original path which was used to open this file. pub fn path<'a>(&'a self) -> &'a Path { &self.path @@ -433,15 +222,241 @@ impl File { } } +/// Unlink a file from the underlying filesystem. +/// +/// # Example +/// +/// use std::rt::io::fs; +/// +/// let p = Path::new("/some/file/path.txt"); +/// fs::unlink(&p); +/// // if we made it here without failing, then the +/// // unlink operation was successful +/// +/// Note that, just because an unlink call was successful, it is not +/// guaranteed that a file is immediately deleted (e.g. depending on +/// platform, other open file descriptors may prevent immediate removal) +/// +/// # Errors +/// +/// This function will raise an `io_error` condition if the path points to a +/// directory, the user lacks permissions to remove the file, or if some +/// other filesystem-level error occurs. +pub fn unlink(path: &Path) { + do io_raise |io| { io.fs_unlink(&path.to_c_str()) }; +} + +/// Given a path, query the file system to get information about a file, +/// directory, etc. This function will traverse symlinks to query +/// information about the destination file. +/// +/// Returns a fully-filled out stat structure on succes, and on failure it +/// will return a dummy stat structure (it is expected that the condition +/// raised is handled as well). +/// +/// # Example +/// +/// use std::rt::io; +/// use std::rt::io::fs; +/// +/// let p = Path::new("/some/file/path.txt"); +/// match io::result(|| fs::stat(&p)) { +/// Ok(stat) => { /* ... */ } +/// Err(e) => { /* handle error */ } +/// } +/// +/// # Errors +/// +/// This call will raise an `io_error` condition if the user lacks the +/// requisite permissions to perform a `stat` call on the given path or if +/// there is no entry in the filesystem at the provided path. +pub fn stat(path: &Path) -> FileStat { + do io_raise |io| { + io.fs_stat(&path.to_c_str()) + }.unwrap_or_else(dummystat) +} + +fn dummystat() -> FileStat { + FileStat { + path: Path::new(""), + size: 0, + kind: io::TypeFile, + perm: 0, + created: 0, + modified: 0, + accessed: 0, + unstable: io::UnstableFileStat { + device: 0, + inode: 0, + rdev: 0, + nlink: 0, + uid: 0, + gid: 0, + blksize: 0, + blocks: 0, + flags: 0, + gen: 0, + } + } +} + +/// Perform the same operation as the `stat` function, except that this +/// function does not traverse through symlinks. This will return +/// information about the symlink file instead of the file that it points +/// to. +/// +/// # Errors +/// +/// See `stat` +pub fn lstat(path: &Path) -> FileStat { + do io_raise |io| { + io.fs_lstat(&path.to_c_str()) + }.unwrap_or_else(dummystat) +} + +/// Rename a file or directory to a new name. +/// +/// # Example +/// +/// use std::rt::io::fs; +/// +/// fs::rename(&Path::new("foo"), &Path::new("bar")); +/// // Oh boy, nothing was raised! +/// +/// # Errors +/// +/// Will raise an `io_error` condition if the provided `path` doesn't exist, +/// the process lacks permissions to view the contents, or if some other +/// intermittent I/O error occurs. +pub fn rename(from: &Path, to: &Path) { + do io_raise |io| { + io.fs_rename(&from.to_c_str(), &to.to_c_str()) + }; +} + +/// Copies the contents of one file to another. This function will also +/// copy the permission bits of the original file to the destination file. +/// +/// Note that if `from` and `to` both point to the same file, then the file +/// will likely get truncated by this operation. +/// +/// # Example +/// +/// use std::rt::io::fs; +/// +/// fs::copy(&Path::new("foo.txt"), &Path::new("bar.txt")); +/// // Oh boy, nothing was raised! +/// +/// # Errors +/// +/// Will raise an `io_error` condition is the following situtations, but is +/// not limited to just these cases: +/// +/// * The `from` path is not a file +/// * The `from` file does not exist +/// * The current process does not have the permission rights to access +/// `from` or write `to` +/// +/// Note that this copy is not atomic in that once the destination is +/// ensured to not exist, there is nothing preventing the destination from +/// being created and then destroyed by this operation. +pub fn copy(from: &Path, to: &Path) { + if !from.is_file() { + return io_error::cond.raise(IoError { + kind: io::MismatchedFileTypeForOperation, + desc: "the source path is not an existing file", + detail: None, + }); + } + + let mut reader = match File::open(from) { Some(f) => f, None => return }; + let mut writer = match File::create(to) { Some(f) => f, None => return }; + let mut buf = [0, ..io::DEFAULT_BUF_SIZE]; + + loop { + match reader.read(buf) { + Some(amt) => writer.write(buf.slice_to(amt)), + None => break + } + } + + chmod(to, from.stat().perm) +} + +/// Changes the permission mode bits found on a file or a directory. This +/// function takes a mask from the `io` module +/// +/// # Example +/// +/// use std::rt::io; +/// use std::rt::io::fs; +/// +/// fs::chmod(&Path::new("file.txt"), io::UserFile); +/// fs::chmod(&Path::new("file.txt"), io::UserRead | io::UserWrite); +/// fs::chmod(&Path::new("dir"), io::UserDir); +/// fs::chmod(&Path::new("file.exe"), io::UserExec); +/// +/// # Errors +/// +/// If this funciton encounters an I/O error, it will raise on the `io_error` +/// condition. Some possible error situations are not having the permission to +/// change the attributes of a file or the file not existing. +pub fn chmod(path: &Path, mode: io::FilePermission) { + do io_raise |io| { + io.fs_chmod(&path.to_c_str(), mode) + }; +} + +/// Change the user and group owners of a file at the specified path. +/// +/// # Errors +/// +/// This funtion will raise on the `io_error` condition on failure. +pub fn chown(path: &Path, uid: int, gid: int) { + do io_raise |io| { io.fs_chown(&path.to_c_str(), uid, gid) }; +} + +/// Creates a new hard link on the filesystem. The `dst` path will be a +/// link pointing to the `src` path. Note that systems often require these +/// two paths to both be located on the same filesystem. +/// +/// # Errors +/// +/// This function will raise on the `io_error` condition on failure. +pub fn link(src: &Path, dst: &Path) { + do io_raise |io| { io.fs_link(&src.to_c_str(), &dst.to_c_str()) }; +} + +/// Creates a new symbolic link on the filesystem. The `dst` path will be a +/// symlink pointing to the `src` path. +/// +/// # Errors +/// +/// This function will raise on the `io_error` condition on failure. +pub fn symlink(src: &Path, dst: &Path) { + do io_raise |io| { io.fs_symlink(&src.to_c_str(), &dst.to_c_str()) }; +} + +/// Reads a symlink, returning the file that the symlink points to. +/// +/// # Errors +/// +/// This function will raise on the `io_error` condition on failure. Failure +/// conditions include reading a file that does not exist or reading a file +/// which is not a symlink. +pub fn readlink(path: &Path) -> Option<Path> { + do io_raise |io| { io.fs_readlink(&path.to_c_str()) } +} + /// Create a new, empty directory at the provided path /// /// # Example /// /// use std::libc::S_IRWXU; -/// use std::rt::io::file; +/// use std::rt::io::fs; /// /// let p = Path::new("/some/dir"); -/// file::mkdir(&p, S_IRWXU as int); +/// fs::mkdir(&p, S_IRWXU as int); /// // If we got here, our directory exists! Horray! /// /// # Errors @@ -459,10 +474,10 @@ pub fn mkdir(path: &Path, mode: FilePermission) { /// /// # Example /// -/// use std::rt::io::file; +/// use std::rt::io::fs; /// /// let p = Path::new("/some/dir"); -/// file::rmdir(&p); +/// fs::rmdir(&p); /// // good riddance, you mean ol' directory /// /// # Errors @@ -480,11 +495,12 @@ pub fn rmdir(path: &Path) { /// /// # Example /// -/// use std::rt::io::file; +/// use std::rt::io::fs; /// +/// // one possible implementation of fs::walk_dir only visiting files /// fn visit_dirs(dir: &Path, cb: &fn(&Path)) { /// if dir.is_dir() { -/// let contents = file::readdir(dir).unwrap(); +/// let contents = fs::readdir(dir).unwrap(); /// for entry in contents.iter() { /// if entry.is_dir() { visit_dirs(entry, cb); } /// else { cb(entry); } @@ -536,7 +552,7 @@ impl Iterator<Path> for WalkIterator { /// # Errors /// /// This function will raise on the `io_error` condition if an error -/// happens, see `file::mkdir` for more information about error conditions +/// happens, see `fs::mkdir` for more information about error conditions /// and performance. pub fn mkdir_recursive(path: &Path, mode: FilePermission) { // tjc: if directory exists but with different permissions, @@ -556,7 +572,7 @@ pub fn mkdir_recursive(path: &Path, mode: FilePermission) { /// # Errors /// /// This function will raise on the `io_error` condition if an error -/// happens. See `file::unlink` and `file::readdir` for possible error +/// happens. See `file::unlink` and `fs::readdir` for possible error /// conditions. pub fn rmdir_recursive(path: &Path) { let children = readdir(path); @@ -564,7 +580,7 @@ pub fn rmdir_recursive(path: &Path) { if child.is_dir() { rmdir_recursive(child); } else { - File::unlink(child); + unlink(child); } } // Directory should now be empty @@ -637,7 +653,7 @@ impl path::Path { /// Consult the `file::stat` documentation for more info. /// /// This call preserves identical runtime/error semantics with `file::stat`. - pub fn stat(&self) -> FileStat { File::stat(self) } + pub fn stat(&self) -> FileStat { stat(self) } /// Boolean value indicator whether the underlying file exists on the local /// filesystem. This will return true if the path points to either a @@ -687,7 +703,9 @@ mod test { use rt::io::{SeekSet, SeekCur, SeekEnd, io_error, Read, Open, ReadWrite}; use rt::io; use str; - use super::{File, rmdir, mkdir, readdir, rmdir_recursive, mkdir_recursive}; + use super::{File, rmdir, mkdir, readdir, rmdir_recursive, mkdir_recursive, + copy, unlink, stat, symlink, link, readlink, chmod, chown, + lstat}; fn tmpdir() -> Path { use os; @@ -697,6 +715,8 @@ mod test { ret } + fn free<T>(_: T) {} + #[test] fn file_test_io_smoke_test() { let message = "it's alright. have a good time"; @@ -714,7 +734,7 @@ mod test { }; assert!(read_str == message.to_owned()); } - File::unlink(filename); + unlink(filename); } #[test] @@ -737,7 +757,7 @@ mod test { do io_error::cond.trap(|_| { called = true; }).inside { - File::unlink(filename); + unlink(filename); } assert!(called); } @@ -762,7 +782,7 @@ mod test { read_stream.read(read_buf); } } - File::unlink(filename); + unlink(filename); let read_str = str::from_utf8(read_mem); assert!(read_str == message.to_owned()); } @@ -786,7 +806,7 @@ mod test { read_stream.read(read_mem); tell_pos_post_read = read_stream.tell(); } - File::unlink(filename); + unlink(filename); let read_str = str::from_utf8(read_mem); assert!(read_str == message.slice(4, 8).to_owned()); assert!(tell_pos_pre_read == set_cursor); @@ -811,7 +831,7 @@ mod test { let mut read_stream = File::open_mode(filename, Open, Read); read_stream.read(read_mem); } - File::unlink(filename); + unlink(filename); let read_str = str::from_utf8(read_mem); assert!(read_str == final_msg.to_owned()); } @@ -847,7 +867,7 @@ mod test { let read_str = str::from_utf8(read_mem); assert!(read_str == chunk_one.to_owned()); } - File::unlink(filename); + unlink(filename); } #[test] @@ -858,9 +878,9 @@ mod test { let msg = "hw"; fs.write(msg.as_bytes()); } - let stat_res = File::stat(filename); + let stat_res = stat(filename); assert_eq!(stat_res.kind, io::TypeFile); - File::unlink(filename); + unlink(filename); } #[test] @@ -885,7 +905,7 @@ mod test { let file = &Path::new("./tmp/fileinfo_check_exists_b_and_a.txt"); File::create(file).write(bytes!("foo")); assert!(file.exists()); - File::unlink(file); + unlink(file); assert!(!file.exists()); } @@ -926,7 +946,7 @@ mod test { }; assert!(expected == read_str); } - File::unlink(f); + unlink(f); } rmdir(dir); } @@ -975,7 +995,7 @@ mod test { fn copy_file_does_not_exist() { let from = Path::new("test/nonexistent-bogus-path"); let to = Path::new("test/other-bogus-path"); - match io::result(|| File::copy(&from, &to)) { + match io::result(|| copy(&from, &to)) { Ok(*) => fail!(), Err(*) => { assert!(!from.exists()); @@ -991,7 +1011,7 @@ mod test { let out = tmpdir.join("out.txt"); File::create(&input).write(bytes!("hello")); - File::copy(&input, &out); + copy(&input, &out); let contents = File::open(&out).read_to_end(); assert_eq!(contents.as_slice(), bytes!("hello")); @@ -1005,7 +1025,7 @@ mod test { let out = tmpdir.join("out"); File::create(&out); - match io::result(|| File::copy(&out, &tmpdir)) { + match io::result(|| copy(&out, &tmpdir)) { Ok(*) => fail!(), Err(*) => {} } rmdir_recursive(&tmpdir); @@ -1019,7 +1039,7 @@ mod test { File::create(&input).write("foo".as_bytes()); File::create(&output).write("bar".as_bytes()); - File::copy(&input, &output); + copy(&input, &output); assert_eq!(File::open(&output).read_to_end(), (bytes!("foo")).to_owned()); @@ -1032,7 +1052,7 @@ mod test { let tmpdir = tmpdir(); let out = tmpdir.join("out"); - match io::result(|| File::copy(&tmpdir, &out)) { + match io::result(|| copy(&tmpdir, &out)) { Ok(*) => fail!(), Err(*) => {} } assert!(!out.exists()); @@ -1046,40 +1066,48 @@ mod test { let out = tmpdir.join("out.txt"); File::create(&input); - File::chmod(&input, io::UserExec); - File::copy(&input, &out); - assert_eq!(out.stat().perm, io::UserExec); + chmod(&input, io::UserRead); + copy(&input, &out); + assert!(out.stat().perm & io::UserWrite == 0); + chmod(&input, io::UserFile); + chmod(&out, io::UserFile); rmdir_recursive(&tmpdir); } #[test] + #[ignore(cfg(windows))] // FIXME(#10264) operation not permitted? fn symlinks_work() { let tmpdir = tmpdir(); let input = tmpdir.join("in.txt"); let out = tmpdir.join("out.txt"); File::create(&input).write("foobar".as_bytes()); - File::symlink(&input, &out); - assert_eq!(File::lstat(&out).kind, io::TypeSymlink); - assert_eq!(File::stat(&out).size, File::stat(&input).size); + symlink(&input, &out); + assert_eq!(lstat(&out).kind, io::TypeSymlink); + assert_eq!(stat(&out).size, stat(&input).size); assert_eq!(File::open(&out).read_to_end(), (bytes!("foobar")).to_owned()); - // can't link to yourself - match io::result(|| File::symlink(&input, &input)) { - Ok(*) => fail!("wanted a failure"), - Err(*) => {} - } - // symlinks can point to things that don't exist - File::symlink(&tmpdir.join("foo"), &tmpdir.join("bar")); + rmdir_recursive(&tmpdir); + } - assert!(File::readlink(&tmpdir.join("bar")).unwrap() == tmpdir.join("bar")); + #[test] + #[ignore(cfg(windows))] // apparently windows doesn't like symlinks + fn symlink_noexist() { + let tmpdir = tmpdir(); + // symlinks can point to things that don't exist + symlink(&tmpdir.join("foo"), &tmpdir.join("bar")); + assert!(readlink(&tmpdir.join("bar")).unwrap() == tmpdir.join("foo")); + rmdir_recursive(&tmpdir); + } - match io::result(|| File::readlink(&tmpdir)) { + #[test] + fn readlink_not_symlink() { + let tmpdir = tmpdir(); + match io::result(|| readlink(&tmpdir)) { Ok(*) => fail!("wanted a failure"), Err(*) => {} } - rmdir_recursive(&tmpdir); } @@ -1090,19 +1118,19 @@ mod test { let out = tmpdir.join("out.txt"); File::create(&input).write("foobar".as_bytes()); - File::link(&input, &out); - assert_eq!(File::lstat(&out).kind, io::TypeFile); - assert_eq!(File::stat(&out).size, File::stat(&input).size); - assert_eq!(File::stat(&out).nlink, 2); + link(&input, &out); + assert_eq!(lstat(&out).kind, io::TypeFile); + assert_eq!(stat(&out).size, stat(&input).size); + assert_eq!(stat(&out).unstable.nlink, 2); assert_eq!(File::open(&out).read_to_end(), (bytes!("foobar")).to_owned()); // can't link to yourself - match io::result(|| File::link(&input, &input)) { + match io::result(|| link(&input, &input)) { Ok(*) => fail!("wanted a failure"), Err(*) => {} } // can't link to something that doesn't exist - match io::result(|| File::link(&tmpdir.join("foo"), &tmpdir.join("bar"))) { + match io::result(|| link(&tmpdir.join("foo"), &tmpdir.join("bar"))) { Ok(*) => fail!("wanted a failure"), Err(*) => {} } @@ -1116,14 +1144,16 @@ mod test { let file = tmpdir.join("in.txt"); File::create(&file); - File::chmod(&file, io::UserRWX); - assert_eq!(File::stat(&file).perm, io::UserRWX); + assert!(stat(&file).perm & io::UserWrite == io::UserWrite); + chmod(&file, io::UserRead); + assert!(stat(&file).perm & io::UserWrite == 0); - match io::result(|| File::chmod(&tmpdir.join("foo"), io::UserRWX)) { + match io::result(|| chmod(&tmpdir.join("foo"), io::UserRWX)) { Ok(*) => fail!("wanted a failure"), Err(*) => {} } + chmod(&file, io::UserFile); rmdir_recursive(&tmpdir); } @@ -1138,6 +1168,7 @@ mod test { file.write(bytes!("foo")); file.fsync(); file.datasync(); + free(file); rmdir_recursive(&tmpdir); } @@ -1151,11 +1182,11 @@ mod test { file.write(bytes!("foo")); // Do some simple things with truncation - assert_eq!(File::stat(&path).size, 3); + assert_eq!(stat(&path).size, 3); file.truncate(10); - assert_eq!(File::stat(&path).size, 10); + assert_eq!(stat(&path).size, 10); file.write(bytes!("bar")); - assert_eq!(File::stat(&path).size, 10); + assert_eq!(stat(&path).size, 10); assert_eq!(File::open(&path).read_to_end(), (bytes!("foobar", 0, 0, 0, 0)).to_owned()); @@ -1163,11 +1194,12 @@ mod test { // Ensure that the intermediate zeroes are all filled in (we're seeked // past the end of the file). file.truncate(2); - assert_eq!(File::stat(&path).size, 2); + assert_eq!(stat(&path).size, 2); file.write(bytes!("wut")); - assert_eq!(File::stat(&path).size, 9); + assert_eq!(stat(&path).size, 9); assert_eq!(File::open(&path).read_to_end(), (bytes!("fo", 0, 0, 0, 0, "wut")).to_owned()); + free(file); rmdir_recursive(&tmpdir); } @@ -1196,19 +1228,19 @@ mod test { Ok(*) => fail!(), Err(*) => {} } } - assert_eq!(File::stat(&tmpdir.join("h")).size, 3); + assert_eq!(stat(&tmpdir.join("h")).size, 3); { let mut f = File::open_mode(&tmpdir.join("h"), io::Append, io::Write).unwrap(); f.write("bar".as_bytes()); } - assert_eq!(File::stat(&tmpdir.join("h")).size, 6); + assert_eq!(stat(&tmpdir.join("h")).size, 6); { let mut f = File::open_mode(&tmpdir.join("h"), io::Truncate, io::Write).unwrap(); f.write("bar".as_bytes()); } - assert_eq!(File::stat(&tmpdir.join("h")).size, 3); + assert_eq!(stat(&tmpdir.join("h")).size, 3); rmdir_recursive(&tmpdir); } diff --git a/src/libstd/rt/io/mod.rs b/src/libstd/rt/io/mod.rs index 510c3470d06..f01ce5012eb 100644 --- a/src/libstd/rt/io/mod.rs +++ b/src/libstd/rt/io/mod.rs @@ -259,7 +259,7 @@ pub use self::stdio::stderr; pub use self::stdio::print; pub use self::stdio::println; -pub use self::file::File; +pub use self::fs::File; pub use self::timer::Timer; pub use self::net::ip::IpAddr; pub use self::net::tcp::TcpListener; @@ -268,8 +268,8 @@ pub use self::net::udp::UdpStream; pub use self::pipe::PipeStream; pub use self::process::Process; -/// Synchronous, non-blocking file I/O. -pub mod file; +/// Synchronous, non-blocking filesystem operations. +pub mod fs; /// Synchronous, in-memory I/O. pub mod pipe; @@ -1155,7 +1155,23 @@ pub struct FileStat { /// milliseconds accessed: u64, - // Various filesytem info + /// Information returned by stat() which is not guaranteed to be + /// platform-independent. This information may be useful on some platforms, + /// but it may have different meanings or no meaning at all on other + /// platforms. + /// + /// Usage of this field is discouraged, but if access is desired then the + /// fields are located here. + #[unstable] + unstable: UnstableFileStat, +} + +/// This structure represents all of the possible information which can be +/// returned from a `stat` syscall which is not contained in the `FileStat` +/// structure. This information is not necessarily platform independent, and may +/// have different meanings or no meaning at all on some platforms. +#[unstable] +pub struct UnstableFileStat { device: u64, inode: u64, rdev: u64, diff --git a/src/libstd/rt/io/native/file.rs b/src/libstd/rt/io/native/file.rs index 4eb473a73a6..35057f475cf 100644 --- a/src/libstd/rt/io/native/file.rs +++ b/src/libstd/rt/io/native/file.rs @@ -737,7 +737,7 @@ mod old_os { #[test] fn test_path_is_dir() { - use rt::io::file::{mkdir_recursive}; + use rt::io::fs::{mkdir_recursive}; use rt::io::{File, UserRWX}; assert!((path_is_dir(&Path::new(".")))); @@ -765,7 +765,7 @@ mod old_os { #[test] fn test_path_exists() { - use rt::io::file::mkdir_recursive; + use rt::io::fs::mkdir_recursive; use rt::io::UserRWX; assert!((path_exists(&Path::new(".")))); diff --git a/src/libstd/rt/io/signal.rs b/src/libstd/rt/io/signal.rs index 1b856ab0755..0f48f83a57e 100644 --- a/src/libstd/rt/io/signal.rs +++ b/src/libstd/rt/io/signal.rs @@ -208,6 +208,7 @@ mod test { #[cfg(windows)] #[test] fn test_io_signal_invalid_signum() { + use rt::io; use super::User1; let mut s = Listener::new(); let mut called = false; diff --git a/src/libstd/rt/sched.rs b/src/libstd/rt/sched.rs index fd4dab60ff3..e71cd92589c 100644 --- a/src/libstd/rt/sched.rs +++ b/src/libstd/rt/sched.rs @@ -836,7 +836,7 @@ impl ClosureConverter for UnsafeTaskReceiver { } // On unix, we read randomness straight from /dev/urandom, but the -// default constructor of an XorShiftRng does this via io::file, which +// default constructor of an XorShiftRng does this via io::fs, which // relies on the scheduler existing, so we have to manually load // randomness. Windows has its own C API for this, so we don't need to // worry there. diff --git a/src/libstd/run.rs b/src/libstd/run.rs index 89784acec8e..74f4ed3d55e 100644 --- a/src/libstd/run.rs +++ b/src/libstd/run.rs @@ -607,8 +607,8 @@ mod tests { let parent_stat = parent_dir.stat(); let child_stat = child_dir.stat(); - assert_eq!(parent_stat.device, child_stat.device); - assert_eq!(parent_stat.inode, child_stat.inode); + assert_eq!(parent_stat.unstable.device, child_stat.unstable.device); + assert_eq!(parent_stat.unstable.inode, child_stat.unstable.inode); } #[test] @@ -624,8 +624,8 @@ mod tests { let parent_stat = parent_dir.stat(); let child_stat = child_dir.stat(); - assert_eq!(parent_stat.device, child_stat.device); - assert_eq!(parent_stat.inode, child_stat.inode); + assert_eq!(parent_stat.unstable.device, child_stat.unstable.device); + assert_eq!(parent_stat.unstable.inode, child_stat.unstable.inode); } #[cfg(unix,not(target_os="android"))] diff --git a/src/test/run-pass/glob-std.rs b/src/test/run-pass/glob-std.rs index 7f684e41c75..897ee9cb88b 100644 --- a/src/test/run-pass/glob-std.rs +++ b/src/test/run-pass/glob-std.rs @@ -21,7 +21,7 @@ use std::rt::io; pub fn main() { fn mk_file(path: &str, directory: bool) { if directory { - io::file::mkdir(&Path::new(path), io::UserRWX); + io::fs::mkdir(&Path::new(path), io::UserRWX); } else { io::File::create(&Path::new(path)); } diff --git a/src/test/run-pass/rename-directory.rs b/src/test/run-pass/rename-directory.rs index 0aa4ae40f9e..fcb57152daa 100644 --- a/src/test/run-pass/rename-directory.rs +++ b/src/test/run-pass/rename-directory.rs @@ -18,8 +18,7 @@ use extra::tempfile::TempDir; use std::os; use std::libc; use std::rt::io; -use std::rt::io::file; -use std::rt::io::File; +use std::rt::io::fs; fn rename_directory() { #[fixed_stack_segment]; @@ -29,7 +28,7 @@ fn rename_directory() { let tmpdir = TempDir::new("rename_directory").expect("rename_directory failed"); let tmpdir = tmpdir.path(); let old_path = tmpdir.join_many(["foo", "bar", "baz"]); - file::mkdir_recursive(&old_path, io::UserRWX); + fs::mkdir_recursive(&old_path, io::UserRWX); let test_file = &old_path.join("temp.txt"); /* Write the temp input file */ @@ -50,8 +49,8 @@ fn rename_directory() { assert_eq!(libc::fclose(ostream), (0u as libc::c_int)); let new_path = tmpdir.join_many(["quux", "blat"]); - file::mkdir_recursive(&new_path, io::UserRWX); - File::rename(&old_path, &new_path.join("newdir")); + fs::mkdir_recursive(&new_path, io::UserRWX); + fs::rename(&old_path, &new_path.join("newdir")); assert!(new_path.join("newdir").is_dir()); assert!(new_path.join_many(["newdir", "temp.txt"]).exists()); } diff --git a/src/test/run-pass/tempfile.rs b/src/test/run-pass/tempfile.rs index 9ac144f5fb5..3a115ab29cf 100644 --- a/src/test/run-pass/tempfile.rs +++ b/src/test/run-pass/tempfile.rs @@ -25,7 +25,7 @@ use std::os; use std::task; use std::cell::Cell; use std::rt::io; -use std::rt::io::file; +use std::rt::io::fs; fn test_tempdir() { let path = { @@ -75,7 +75,7 @@ fn test_rm_tempdir() { path = tmp.unwrap(); } assert!(path.exists()); - file::rmdir_recursive(&path); + fs::rmdir_recursive(&path); assert!(!path.exists()); } @@ -86,17 +86,17 @@ fn recursive_mkdir_rel() { let cwd = os::getcwd(); debug!("recursive_mkdir_rel: Making: {} in cwd {} [{:?}]", path.display(), cwd.display(), path.exists()); - file::mkdir_recursive(&path, io::UserRWX); + fs::mkdir_recursive(&path, io::UserRWX); assert!(path.is_dir()); - file::mkdir_recursive(&path, io::UserRWX); + fs::mkdir_recursive(&path, io::UserRWX); assert!(path.is_dir()); } fn recursive_mkdir_dot() { let dot = Path::new("."); - file::mkdir_recursive(&dot, io::UserRWX); + fs::mkdir_recursive(&dot, io::UserRWX); let dotdot = Path::new(".."); - file::mkdir_recursive(&dotdot, io::UserRWX); + fs::mkdir_recursive(&dotdot, io::UserRWX); } fn recursive_mkdir_rel_2() { @@ -104,13 +104,13 @@ fn recursive_mkdir_rel_2() { let cwd = os::getcwd(); debug!("recursive_mkdir_rel_2: Making: {} in cwd {} [{:?}]", path.display(), cwd.display(), path.exists()); - file::mkdir_recursive(&path, io::UserRWX); + fs::mkdir_recursive(&path, io::UserRWX); assert!(path.is_dir()); assert!(path.dir_path().is_dir()); let path2 = Path::new("quux/blat"); debug!("recursive_mkdir_rel_2: Making: {} in cwd {}", path2.display(), cwd.display()); - file::mkdir_recursive(&path2, io::UserRWX); + fs::mkdir_recursive(&path2, io::UserRWX); assert!(path2.is_dir()); assert!(path2.dir_path().is_dir()); } @@ -125,11 +125,11 @@ pub fn test_rmdir_recursive_ok() { let root = tmpdir.join("foo"); debug!("making {}", root.display()); - file::mkdir(&root, rwx); - file::mkdir(&root.join("foo"), rwx); - file::mkdir(&root.join("foo").join("bar"), rwx); - file::mkdir(&root.join("foo").join("bar").join("blat"), rwx); - file::rmdir_recursive(&root); + fs::mkdir(&root, rwx); + fs::mkdir(&root.join("foo"), rwx); + fs::mkdir(&root.join("foo").join("bar"), rwx); + fs::mkdir(&root.join("foo").join("bar").join("blat"), rwx); + fs::rmdir_recursive(&root); assert!(!root.exists()); assert!(!root.join("bar").exists()); assert!(!root.join("bar").join("blat").exists()); |
