This commit moves all thread-blocking I/O functions from the std::os module.
Their replacements can be found in either std::rt::io::file or in a hidden
"old_os" module inside of native::file. I didn't want to outright delete these
functions because they have a lot of special casing learned over time for each
OS/platform, and I imagine that these will someday get integrated into a
blocking implementation of IoFactory. For now, they're moved to a private module
to prevent bitrot and still have tests to ensure that they work.
I've also expanded the extensions to a few more methods defined on Path, most of
which were previously defined in std::os but now have non-thread-blocking
implementations as part of using the current IoFactory.
The api of io::file is in flux, but I plan on changing it in the next commit as
well.
Closes #10057
CTEST_MODE_rpass = run-pass
CTEST_RUNTOOL_rpass = $(CTEST_RUNTOOL)
-CTEST_SRC_BASE_rpass-full = run-pass-full
-CTEST_BUILD_BASE_rpass-full = run-pass-full
+CTEST_SRC_BASE_rpass-full = run-pass-fulldeps
+CTEST_BUILD_BASE_rpass-full = run-pass-fulldeps
CTEST_MODE_rpass-full = run-pass
CTEST_RUNTOOL_rpass-full = $(CTEST_RUNTOOL)
PRETTY_DEPS_pretty-bench = $(BENCH_TESTS)
PRETTY_DEPS_pretty-pretty = $(PRETTY_TESTS)
PRETTY_DIRNAME_pretty-rpass = run-pass
-PRETTY_DIRNAME_pretty-rpass-full = run-pass-full
+PRETTY_DIRNAME_pretty-rpass-full = run-pass-fulldeps
PRETTY_DIRNAME_pretty-rfail = run-fail
PRETTY_DIRNAME_pretty-bench = bench
PRETTY_DIRNAME_pretty-pretty = pretty
use std::os;
use std::rt;
+use std::rt::io::file;
use extra::getopts;
use extra::getopts::groups::{optopt, optflag, reqopt};
debug!("making tests from {}",
config.src_base.display());
let mut tests = ~[];
- let dirs = os::list_dir_path(&config.src_base);
+ let dirs = file::readdir(&config.src_base);
for file in dirs.iter() {
let file = file.clone();
debug!("inspecting file {}", file.display());
// option. This file may not be copied, modified, or distributed
// except according to those terms.
+use std::rt::io::buffered::BufferedReader;
+use std::rt::io::file;
+
pub struct ExpectedError { line: uint, kind: ~str, msg: ~str }
// Load any test directives embedded in the file
pub fn load_errors(testfile: &Path) -> ~[ExpectedError] {
- use std::rt::io::Open;
- use std::rt::io::file::FileInfo;
- use std::rt::io::buffered::BufferedReader;
let mut error_patterns = ~[];
- let mut rdr = BufferedReader::new(testfile.open_reader(Open).unwrap());
+ let mut rdr = BufferedReader::new(file::open(testfile).unwrap());
let mut line_num = 1u;
loop {
let ln = match rdr.read_line() {
}
fn iter_header(testfile: &Path, it: &fn(&str) -> bool) -> bool {
- use std::rt::io::Open;
- use std::rt::io::file::FileInfo;
use std::rt::io::buffered::BufferedReader;
+ use std::rt::io::file;
- let mut rdr = BufferedReader::new(testfile.open_reader(Open).unwrap());
+ let mut rdr = BufferedReader::new(file::open(testfile).unwrap());
loop {
let ln = match rdr.read_line() {
Some(ln) => ln, None => break
use std::cell::Cell;
use std::rt::io;
-use std::rt::io::Writer;
-use std::rt::io::Reader;
-use std::rt::io::file::FileInfo;
+use std::rt::io::file;
use std::os;
use std::str;
use std::task::{spawn_sched, SingleThreaded};
let rounds =
match props.pp_exact { Some(_) => 1, None => 2 };
- let src = testfile.open_reader(io::Open).read_to_end();
+ let src = file::open(testfile).read_to_end();
let src = str::from_utf8_owned(src);
let mut srcs = ~[src];
let mut expected = match props.pp_exact {
Some(ref file) => {
let filepath = testfile.dir_path().join(file);
- let s = filepath.open_reader(io::Open).read_to_end();
+ let s = file::open(&filepath).read_to_end();
str::from_utf8_owned(s)
}
None => { srcs[srcs.len() - 2u].clone() }
}
fn ensure_dir(path: &Path) {
- if os::path_is_dir(path) { return; }
- if !os::make_dir(path, 0x1c0i32) {
- fail!("can't make dir {}", path.display());
- }
+ if path.is_dir() { return; }
+ file::mkdir(path, io::UserRWX);
}
fn compose_and_run(config: &config, testfile: &Path,
fn dump_output_file(config: &config, testfile: &Path,
out: &str, extension: &str) {
let outfile = make_out_name(config, testfile, extension);
- outfile.open_writer(io::CreateOrTruncate).write(out.as_bytes());
+ file::create(&outfile).write(out.as_bytes());
}
fn make_out_name(config: &config, testfile: &Path, extension: &str) -> Path {
fn _arm_push_aux_shared_library(config: &config, testfile: &Path) {
let tdir = aux_output_dir_name(config, testfile);
- let dirs = os::list_dir_path(&tdir);
+ let dirs = file::readdir(&tdir);
for file in dirs.iter() {
if file.extension_str() == Some("so") {
// FIXME (#9639): This needs to handle non-utf8 paths
fn count_extracted_lines(p: &Path) -> uint {
- let x = p.with_extension("ll").open_reader(io::Open).read_to_end();
+ let x = file::open(&p.with_extension("ll")).read_to_end();
let x = str::from_utf8_owned(x);
x.line_iter().len()
}
*/
use std::{os, path};
+use std::rt::io;
+use std::rt::io::file;
use std::path::is_sep;
use sort;
}
fn list_dir_sorted(path: &Path) -> ~[Path] {
- let mut children = os::list_dir_path(path);
- sort::quick_sort(children, |p1, p2| p2.filename().unwrap() <= p1.filename().unwrap());
- children
+ match io::result(|| file::readdir(path)) {
+ Ok(children) => {
+ let mut children = children;
+ sort::quick_sort(children, |p1, p2| p2.filename() <= p1.filename());
+ children
+ }
+ Err(*) => ~[]
+ }
}
/**
use std::os;
use std::rand::Rng;
use std::rand;
+use std::rt::io;
+use std::rt::io::file;
/// A wrapper for a path to temporary directory implementing automatic
/// scope-pased deletion.
let mut r = rand::rng();
for _ in range(0u, 1000) {
let p = tmpdir.join(r.gen_ascii_str(16) + suffix);
- if os::make_dir(&p, 0x1c0) { // 700
- return Some(TempDir { path: Some(p) });
+ match io::result(|| file::mkdir(&p, io::UserRWX)) {
+ Err(*) => {}
+ Ok(()) => return Some(TempDir { path: Some(p) })
}
}
None
impl Drop for TempDir {
fn drop(&mut self) {
for path in self.path.iter() {
- os::remove_dir_recursive(path);
+ if path.exists() {
+ file::rmdir_recursive(path);
+ }
}
}
}
use std::{os, str};
use std::os::getenv;
use std::rt::io;
-use std::rt::io::file::FileInfo;
+use std::rt::io::file;
/// Return path to database entry for `term`
pub fn get_dbpath_for_term(term: &str) -> Option<~Path> {
// Look for the terminal in all of the search directories
for p in dirs_to_search.iter() {
- if os::path_exists(p) {
+ if p.exists() {
let f = str::from_char(first_char);
let newp = p.join_many([f.as_slice(), term]);
- if os::path_exists(&newp) {
+ if newp.exists() {
return Some(~newp);
}
// on some installations the dir is named after the hex of the char (e.g. OS X)
let f = format!("{:x}", first_char as uint);
let newp = p.join_many([f.as_slice(), term]);
- if os::path_exists(&newp) {
+ if newp.exists() {
return Some(~newp);
}
}
/// Return open file for `term`
pub fn open(term: &str) -> Result<@mut io::Reader, ~str> {
match get_dbpath_for_term(term) {
- Some(x) => Ok(@mut x.open_reader(io::Open).unwrap() as @mut io::Reader),
+ Some(x) => Ok(@mut file::open(x) as @mut io::Reader),
None => Err(format!("could not find terminfo entry for {}", term))
}
}
use std::clone::Clone;
use std::comm::{stream, SharedChan, GenericPort, GenericChan};
use std::rt::io;
-use std::rt::io::file::FileInfo;
+use std::rt::io::file;
use std::task;
use std::to_str::ToStr;
use std::f64;
impl ConsoleTestState {
pub fn new(opts: &TestOpts) -> ConsoleTestState {
let log_out = match opts.logfile {
- Some(ref path) => {
- let out = path.open_writer(io::CreateOrTruncate);
- Some(@mut out as @mut io::Writer)
- },
+ Some(ref path) => Some(@mut file::create(path) as @mut io::Writer),
None => None
};
let out = @mut io::stdio::stdout() as @mut io::Writer;
/// Load MetricDiff from a file.
pub fn load(p: &Path) -> MetricMap {
- assert!(os::path_exists(p));
- let f = @mut p.open_reader(io::Open) as @mut io::Reader;
+ assert!(p.exists());
+ let f = @mut file::open(p) as @mut io::Reader;
let mut decoder = json::Decoder(json::from_reader(f).unwrap());
MetricMap(Decodable::decode(&mut decoder))
}
/// Write MetricDiff to a file.
pub fn save(&self, p: &Path) {
- let f = @mut p.open_writer(io::CreateOrTruncate);
- self.to_json().to_pretty_writer(f as @mut io::Writer);
+ self.to_json().to_pretty_writer(@mut file::create(p) as @mut io::Writer);
}
/// Compare against another MetricMap. Optionally compare all
/// `MetricChange`s are `Regression`. Returns the diff as well
/// as a boolean indicating whether the ratchet succeeded.
pub fn ratchet(&self, p: &Path, pct: Option<f64>) -> (MetricDiff, bool) {
- let old = if os::path_exists(p) {
+ let old = if p.exists() {
MetricMap::load(p)
} else {
MetricMap::new()
#[test]
fn test_serialize_round_trip() {
- use std;
use ebml;
use serialize::{Encodable, Decodable};
use treemap::TreeMap;
use std::cell::Cell;
use std::comm::{PortOne, oneshot};
-use std::{os, str, task};
+use std::{str, task};
use std::rt::io;
-use std::rt::io::Writer;
-use std::rt::io::Reader;
+use std::rt::io::file;
use std::rt::io::Decorator;
use std::rt::io::mem::MemWriter;
-use std::rt::io::file::FileInfo;
/**
*
db_cache: TreeMap::new(),
db_dirty: false
};
- if os::path_exists(&rslt.db_filename) {
+ if rslt.db_filename.exists() {
rslt.load();
}
rslt
// FIXME #4330: This should have &mut self and should set self.db_dirty to false.
fn save(&self) {
- let f = @mut self.db_filename.open_writer(io::CreateOrTruncate);
+ let f = @mut file::create(&self.db_filename);
self.db_cache.to_json().to_pretty_writer(f as @mut io::Writer);
}
fn load(&mut self) {
assert!(!self.db_dirty);
- assert!(os::path_exists(&self.db_filename));
- let f = self.db_filename.open_reader(io::Open);
- match f {
- None => fail!("Couldn't load workcache database {}",
- self.db_filename.display()),
- Some(r) =>
- match json::from_reader(@mut r as @mut io::Reader) {
+ assert!(self.db_filename.exists());
+ match io::result(|| file::open(&self.db_filename)) {
+ Err(e) => fail!("Couldn't load workcache database {}: {}",
+ self.db_filename.display(),
+ e.desc),
+ Ok(r) =>
+ match json::from_reader(@mut r.unwrap() as @mut io::Reader) {
Err(e) => fail!("Couldn't parse workcache database (from file {}): {}",
self.db_filename.display(), e.to_str()),
Ok(r) => {
#[test]
fn test() {
use std::{os, run};
- use std::rt::io::Reader;
+ use std::rt::io::file;
use std::str::from_utf8_owned;
// Create a path to a new file 'filename' in the directory in which
// this test is running.
fn make_path(filename: ~str) -> Path {
let pth = os::self_exe_path().expect("workcache::test failed").with_filename(filename);
- if os::path_exists(&pth) {
- os::remove_file(&pth);
+ if pth.exists() {
+ file::unlink(&pth);
}
return pth;
}
let pth = make_path(~"foo.c");
- {
- pth.open_writer(io::Create).write(bytes!("int main() { return 0; }"));
- }
+ file::create(&pth).write(bytes!("int main() { return 0; }"));
let db_path = make_path(~"db.json");
let subcx = cx.clone();
let pth = pth.clone();
- let file_content = from_utf8_owned(pth.open_reader(io::Open).read_to_end());
+ let file_content = from_utf8_owned(file::open(&pth).read_to_end());
// FIXME (#9639): This needs to handle non-utf8 paths
prep.declare_input("file", pth.as_str().unwrap(), file_content);
use std::hash::Streaming;
use std::hash;
use std::os::consts::{macos, freebsd, linux, android, win32};
-use std::os;
use std::ptr;
-use std::rt::io::Writer;
use std::run;
use std::str;
use std::vec;
+use std::rt::io::file;
use syntax::ast;
use syntax::ast_map::{path, path_mod, path_name, path_pretty_name};
use syntax::attr;
// Remove the temporary object file if we aren't saving temps
if !sess.opts.save_temps {
- if ! os::remove_file(obj_filename) {
- sess.warn(format!("failed to delete object file `{}`",
- obj_filename.display()));
- }
+ file::unlink(obj_filename);
}
}
fn is_writeable(p: &Path) -> bool {
+ use std::rt::io;
use std::libc::consts::os::posix88::S_IWUSR;
- !os::path_exists(p) ||
- (match p.get_mode() {
- None => false,
- Some(m) => m & S_IWUSR as uint == S_IWUSR as uint
+ !p.exists() ||
+ (match io::result(|| p.stat()) {
+ Err(*) => false,
+ Ok(m) => (m.mode as uint) & S_IWUSR as uint == S_IWUSR as uint
})
}
use std::hashmap::{HashMap,HashSet};
use std::rt::io;
+use std::rt::io::file;
use std::rt::io::mem::MemReader;
use std::os;
use std::vec;
// Remove assembly source unless --save-temps was specified
if !sess.opts.save_temps {
- os::remove_file(&asm_filename);
+ file::unlink(&asm_filename);
}
} else {
time(sess.time_passes(), "LLVM passes", (), |_|
use std::option;
use std::os;
+use std::rt::io;
+use std::rt::io::file;
use std::hashmap::HashSet;
pub enum FileMatch { FileMatches, FileDoesntMatch }
pub fn search(filesearch: @FileSearch, pick: pick) {
do filesearch.for_each_lib_search_path() |lib_search_path| {
debug!("searching {}", lib_search_path.display());
- let r = os::list_dir_path(lib_search_path);
- let mut rslt = FileDoesntMatch;
- for path in r.iter() {
- debug!("testing {}", path.display());
- let maybe_picked = pick(path);
- match maybe_picked {
- FileMatches => {
- debug!("picked {}", path.display());
- rslt = FileMatches;
- }
- FileDoesntMatch => {
- debug!("rejected {}", path.display());
+ match io::result(|| file::readdir(lib_search_path)) {
+ Ok(files) => {
+ let mut rslt = FileDoesntMatch;
+ for path in files.iter() {
+ debug!("testing {}", path.display());
+ let maybe_picked = pick(path);
+ match maybe_picked {
+ FileMatches => {
+ debug!("picked {}", path.display());
+ rslt = FileMatches;
+ }
+ FileDoesntMatch => {
+ debug!("rejected {}", path.display());
+ }
+ }
}
+ rslt
}
+ Err(*) => FileDoesntMatch,
}
- rslt
};
}
break
}
cwd.set_filename(".rust");
- if !env_rust_path.contains(&cwd) && os::path_exists(&cwd) {
+ if !env_rust_path.contains(&cwd) && cwd.exists() {
env_rust_path.push(cwd.clone());
}
cwd.pop();
let h = os::homedir();
for h in h.iter() {
let p = h.join(".rust");
- if !env_rust_path.contains(&p) && os::path_exists(&p) {
+ if !env_rust_path.contains(&p) && p.exists() {
env_rust_path.push(p);
}
}
use std::hashmap::{HashMap, HashSet};
use std::local_data;
use std::rt::io::buffered::BufferedWriter;
-use std::rt::io::file::{FileInfo, DirectoryInfo};
-use std::rt::io::file;
use std::rt::io;
-use std::rt::io::Reader;
+use std::rt::io::file;
use std::os;
use std::str;
use std::task;
// Publish the search index
{
dst.push("search-index.js");
- let mut w = BufferedWriter::new(dst.open_writer(io::CreateOrTruncate));
- let w = &mut w as &mut io::Writer;
+ let mut w = BufferedWriter::new(file::create(&dst).unwrap());
+ let w = &mut w as &mut Writer;
write!(w, "var searchIndex = [");
for (i, item) in cache.search_index.iter().enumerate() {
if i > 0 { write!(w, ","); }
/// Writes the entire contents of a string to a destination, not attempting to
/// catch any errors.
fn write(dst: Path, contents: &str) {
- let mut w = dst.open_writer(io::CreateOrTruncate);
- w.write(contents.as_bytes());
+ file::create(&dst).write(contents.as_bytes());
}
/// Makes a directory on the filesystem, failing the task if an error occurs and
fail!()
}).inside {
if !path.is_dir() {
- file::mkdir(path);
+ file::mkdir(path, io::UserRWX);
}
}
}
let mut contents = ~[];
{
let mut buf = [0, ..1024];
- let r = do io::io_error::cond.trap(|_| {}).inside {
- p.open_reader(io::Open)
- };
// If we couldn't open this file, then just returns because it
// probably means that it's some standard library macro thing and we
// can't have the source to it anyway.
- let mut r = match r {
- Some(r) => r,
+ let mut r = match io::result(|| file::open(&p)) {
+ Ok(r) => r,
// eew macro hacks
- None => return filename == "<std-macros>"
+ Err(*) => return filename == "<std-macros>"
};
// read everything
}
cur.push(p.filename().expect("source has no filename") + bytes!(".html"));
- let w = cur.open_writer(io::CreateOrTruncate);
- let mut w = BufferedWriter::new(w);
+ let mut w = BufferedWriter::new(file::create(&cur).unwrap());
let title = cur.filename_display().with_str(|s| format!("{} -- source", s));
let page = layout::Page {
ty: "source",
root_path: root_path,
};
- layout::render(&mut w as &mut io::Writer, &self.cx.layout,
+ layout::render(&mut w as &mut Writer, &self.cx.layout,
&page, &(""), &Source(contents.as_slice()));
w.flush();
return true;
///
/// The rendering driver uses this closure to queue up more work.
fn item(&mut self, item: clean::Item, f: &fn(&mut Context, clean::Item)) {
- fn render(w: io::file::FileWriter, cx: &mut Context, it: &clean::Item,
+ fn render(w: file::FileWriter, cx: &mut Context, it: &clean::Item,
pushname: bool) {
// A little unfortunate that this is done like this, but it sure
// does make formatting *a lot* nicer.
// of the pain by using a buffered writer instead of invoking the
// write sycall all the time.
let mut writer = BufferedWriter::new(w);
- layout::render(&mut writer as &mut io::Writer, &cx.layout, &page,
+ layout::render(&mut writer as &mut Writer, &cx.layout, &page,
&Sidebar{ cx: cx, item: it },
&Item{ cx: cx, item: it });
writer.flush();
do self.recurse(name) |this| {
let item = item.take();
let dst = this.dst.join("index.html");
- let writer = dst.open_writer(io::CreateOrTruncate);
- render(writer.unwrap(), this, &item, false);
+ render(file::create(&dst).unwrap(), this, &item, false);
let m = match item.inner {
clean::ModuleItem(m) => m,
// pages dedicated to them.
_ if item.name.is_some() => {
let dst = self.dst.join(item_path(&item));
- let writer = dst.open_writer(io::CreateOrTruncate);
- render(writer.unwrap(), self, &item, true);
+ render(file::create(&dst).unwrap(), self, &item, true);
}
_ => {}
}
}
-fn document(w: &mut io::Writer, item: &clean::Item) {
+fn document(w: &mut Writer, item: &clean::Item) {
match item.doc_value() {
Some(s) => {
write!(w, "<div class='docblock'>{}</div>", Markdown(s));
}
}
-fn item_module(w: &mut io::Writer, cx: &Context,
+fn item_module(w: &mut Writer, cx: &Context,
item: &clean::Item, items: &[clean::Item]) {
document(w, item);
debug!("{:?}", items);
write!(w, "</table>");
}
-fn item_function(w: &mut io::Writer, it: &clean::Item, f: &clean::Function) {
+fn item_function(w: &mut Writer, it: &clean::Item, f: &clean::Function) {
write!(w, "<pre class='fn'>{vis}{purity}fn {name}{generics}{decl}</pre>",
vis = VisSpace(it.visibility),
purity = PuritySpace(f.purity),
document(w, it);
}
-fn item_trait(w: &mut io::Writer, it: &clean::Item, t: &clean::Trait) {
+fn item_trait(w: &mut Writer, it: &clean::Item, t: &clean::Trait) {
let mut parents = ~"";
if t.parents.len() > 0 {
parents.push_str(": ");
// Trait documentation
document(w, it);
- fn meth(w: &mut io::Writer, m: &clean::TraitMethod) {
+ fn meth(w: &mut Writer, m: &clean::TraitMethod) {
write!(w, "<h3 id='{}.{}' class='method'><code>",
shortty(m.item()),
*m.item().name.get_ref());
}
}
-fn render_method(w: &mut io::Writer, meth: &clean::Item, withlink: bool) {
- fn fun(w: &mut io::Writer, it: &clean::Item, purity: ast::purity,
+fn render_method(w: &mut Writer, meth: &clean::Item, withlink: bool) {
+ fn fun(w: &mut Writer, it: &clean::Item, purity: ast::purity,
g: &clean::Generics, selfty: &clean::SelfTy, d: &clean::FnDecl,
withlink: bool) {
write!(w, "{}fn {withlink, select,
}
}
-fn item_struct(w: &mut io::Writer, it: &clean::Item, s: &clean::Struct) {
+fn item_struct(w: &mut Writer, it: &clean::Item, s: &clean::Struct) {
write!(w, "<pre class='struct'>");
render_struct(w, it, Some(&s.generics), s.struct_type, s.fields,
s.fields_stripped, "", true);
render_methods(w, it);
}
-fn item_enum(w: &mut io::Writer, it: &clean::Item, e: &clean::Enum) {
+fn item_enum(w: &mut Writer, it: &clean::Item, e: &clean::Enum) {
write!(w, "<pre class='enum'>{}enum {}{}",
VisSpace(it.visibility),
it.name.get_ref().as_slice(),
render_methods(w, it);
}
-fn render_struct(w: &mut io::Writer, it: &clean::Item,
+fn render_struct(w: &mut Writer, it: &clean::Item,
g: Option<&clean::Generics>,
ty: doctree::StructType,
fields: &[clean::Item],
}
}
-fn render_methods(w: &mut io::Writer, it: &clean::Item) {
+fn render_methods(w: &mut Writer, it: &clean::Item) {
do local_data::get(cache_key) |cache| {
let cache = cache.unwrap();
do cache.read |c| {
}
}
-fn render_impl(w: &mut io::Writer, i: &clean::Impl, dox: &Option<~str>) {
+fn render_impl(w: &mut Writer, i: &clean::Impl, dox: &Option<~str>) {
write!(w, "<h3 class='impl'><code>impl{} ", i.generics);
let trait_id = match i.trait_ {
Some(ref ty) => {
None => {}
}
- fn docmeth(w: &mut io::Writer, item: &clean::Item) -> bool {
+ fn docmeth(w: &mut Writer, item: &clean::Item) -> bool {
write!(w, "<h4 id='method.{}' class='method'><code>",
*item.name.get_ref());
render_method(w, item, false);
write!(w, "</div>");
}
-fn item_typedef(w: &mut io::Writer, it: &clean::Item, t: &clean::Typedef) {
+fn item_typedef(w: &mut Writer, it: &clean::Item, t: &clean::Typedef) {
write!(w, "<pre class='typedef'>type {}{} = {};</pre>",
it.name.get_ref().as_slice(),
t.generics,
}
write!(fmt.buf, "</p>");
- fn block(w: &mut io::Writer, short: &str, longty: &str,
+ fn block(w: &mut Writer, short: &str, longty: &str,
cur: &clean::Item, cx: &Context) {
let items = match cx.sidebar.find_equiv(&short) {
Some(items) => items.as_slice(),
use std::cell::Cell;
use std::local_data;
-use std::rt::io::Writer;
-use std::rt::io::file::FileInfo;
use std::rt::io;
+use std::rt::io::file;
use std::rt::io::mem::MemWriter;
use std::rt::io::Decorator;
use std::str;
/// This input format purely deserializes the json output file. No passes are
/// run over the deserialized output.
fn json_input(input: &str) -> Result<Output, ~str> {
- let input = match Path::new(input).open_reader(io::Open) {
+ let input = match file::open(&Path::new(input)) {
Some(f) => f,
None => return Err(format!("couldn't open {} for reading", input)),
};
json.insert(~"crate", crate_json);
json.insert(~"plugins", json::Object(plugins_json));
- let mut file = dst.open_writer(io::Create).unwrap();
+ let mut file = file::create(&dst).unwrap();
let output = json::Object(json).to_str();
file.write(output.as_bytes());
}
pub use source_control::{safe_git_clone, git_clone_url};
-use std::{os, run};
+use std::run;
use extra::arc::{Arc,RWArc};
use extra::workcache;
use extra::workcache::{Database, Logger, FreshnessMap};
fn file_is_fresh(path: &str, in_hash: &str) -> bool {
let path = Path::new(path);
- os::path_exists(&path) && in_hash == digest_file_with_date(&path)
+ path.exists() && in_hash == digest_file_with_date(&path)
}
fn binary_is_fresh(path: &str, in_hash: &str) -> bool {
let path = Path::new(path);
- os::path_exists(&path) && in_hash == digest_only_date(&path)
+ path.exists() && in_hash == digest_only_date(&path)
}
pub fn new_workcache_context(p: &Path) -> workcache::Context {
use rustc::driver::session::{OptLevel, No};
use std::hashmap::HashSet;
-use std::os;
#[deriving(Clone)]
pub struct Context {
debug!("Checking whether {} is in target", sysroot.display());
let mut p = sysroot.dir_path();
p.set_filename("rustc");
- os::path_is_dir(&p)
+ p.is_dir()
}
impl RustcFlags {
use rustc::metadata::filesearch::rust_path;
use path_util::*;
use std::os;
+use std::rt::io;
+use std::rt::io::file;
pub fn list_installed_packages(f: &fn(&PkgId) -> bool) -> bool {
let workspaces = rust_path();
for p in workspaces.iter() {
- let binfiles = os::list_dir(&p.join("bin"));
+ let binfiles = do io::ignore_io_error { file::readdir(&p.join("bin")) };
for exec in binfiles.iter() {
// FIXME (#9639): This needs to handle non-utf8 paths
match exec.filestem_str() {
}
}
}
- let libfiles = os::list_dir(&p.join("lib"));
+ let libfiles = do io::ignore_io_error { file::readdir(&p.join("lib")) };
for lib in libfiles.iter() {
debug!("Full name: {}", lib.display());
match has_library(lib) {
}
pub fn has_library(p: &Path) -> Option<~str> {
- let files = os::list_dir(p);
+ let files = do io::ignore_io_error { file::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");
use std::{os, result, run, str, task};
use std::hashmap::HashSet;
+use std::rt::io;
+use std::rt::io::file;
pub use std::path::Path;
use extra::workcache;
use syntax::{ast, diagnostic};
use messages::{error, warn, note};
use path_util::{build_pkg_id_in_workspace, built_test_in_workspace};
-use path_util::{U_RWX, in_rust_path};
+use path_util::in_rust_path;
use path_util::{built_executable_in_workspace, built_library_in_workspace, default_workspace};
use path_util::{target_executable_in_workspace, target_library_in_workspace, dir_has_crate_file};
use source_control::{CheckedOutSources, is_git_dir, make_read_only};
// We expect that p is relative to the package source's start directory,
// so check that assumption
debug!("JustOne: p = {}", p.display());
- assert!(os::path_exists(&pkg_src.start_dir.join(p)));
+ assert!(pkg_src.start_dir.join(p).exists());
if is_lib(p) {
PkgSrc::push_crate(&mut pkg_src.libs, 0, p);
} else if is_main(p) {
let dir = build_pkg_id_in_workspace(id, workspace);
note(format!("Cleaning package {} (removing directory {})",
id.to_str(), dir.display()));
- if os::path_exists(&dir) {
- os::remove_dir_recursive(&dir);
+ if dir.exists() {
+ file::rmdir_recursive(&dir);
note(format!("Removed directory {}", dir.display()));
}
build_inputs: &[Path],
target_workspace: &Path,
id: &PkgId) -> ~[~str] {
- use conditions::copy_failed::cond;
debug!("install_no_build: assuming {} comes from {} with target {}",
id.to_str(), build_workspace.display(), target_workspace.display());
for exec in subex.iter() {
debug!("Copying: {} -> {}", exec.display(), sub_target_ex.display());
- if !(os::mkdir_recursive(&sub_target_ex.dir_path(), U_RWX) &&
- os::copy_file(exec, &sub_target_ex)) {
- cond.raise(((*exec).clone(), sub_target_ex.clone()));
- }
+ file::mkdir_recursive(&sub_target_ex.dir_path(), io::UserRWX);
+ file::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(),
.clone().expect(format!("I built {} but apparently \
didn't install it!", lib.display()));
target_lib.set_filename(lib.filename().expect("weird target lib"));
- if !(os::mkdir_recursive(&target_lib.dir_path(), U_RWX) &&
- os::copy_file(lib, &target_lib)) {
- cond.raise(((*lib).clone(), target_lib.clone()));
- }
+ file::mkdir_recursive(&target_lib.dir_path(), io::UserRWX);
+ file::copy(lib, &target_lib);
debug!("3. discovering output {}", target_lib.display());
exe_thing.discover_output("binary",
target_lib.as_str().unwrap(),
}
fn init(&self) {
- os::mkdir_recursive(&Path::new("src"), U_RWX);
- os::mkdir_recursive(&Path::new("lib"), U_RWX);
- os::mkdir_recursive(&Path::new("bin"), U_RWX);
- os::mkdir_recursive(&Path::new("build"), U_RWX);
+ 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);
}
fn uninstall(&self, _id: &str, _vers: Option<~str>) {
use version::{try_getting_version, try_getting_local_version,
Version, NoVersion, split_version};
-use std::rt::io::Writer;
use std::hash::Streaming;
use std::hash;
use target::*;
use package_id::PkgId;
-use std::path::Path;
+use std::rt::io;
+use std::rt::io::file;
use std::os;
use context::*;
use crate::Crate;
debug!("Checking dirs: {:?}", to_try.map(|p| p.display().to_str()).connect(":"));
- let path = to_try.iter().find(|&d| os::path_exists(d));
+ let path = to_try.iter().find(|&d| d.exists());
// See the comments on the definition of PkgSrc
let mut build_in_destination = use_rust_path_hack;
let package_id = PkgId::new(prefix.as_str().unwrap());
let path = build_dir.join(&package_id.path);
debug!("in loop: checking if {} is a directory", path.display());
- if os::path_is_dir(&path) {
+ if path.is_dir() {
let ps = PkgSrc::new(source_workspace,
destination_workspace,
use_rust_path_hack,
debug!("For package id {}, returning {}", id.to_str(), dir.display());
- if !os::path_is_dir(&dir) {
+ if !dir.is_dir() {
cond.raise((id.clone(), ~"supplied path for package dir is a \
non-directory"));
}
debug!("Checking whether {} (path = {}) exists locally. Cwd = {}, does it? {:?}",
pkgid.to_str(), pkgid.path.display(),
cwd.display(),
- os::path_exists(&pkgid.path));
+ pkgid.path.exists());
match safe_git_clone(&pkgid.path, &pkgid.version, local) {
CheckedOutSources => {
// Move clone_target to local.
// First, create all ancestor directories.
let moved = make_dir_rwx_recursive(&local.dir_path())
- && os::rename_file(&clone_target, local);
+ && io::result(|| file::rename(&clone_target, local)).is_ok();
if moved { Some(local.clone()) }
else { None }
}
pub fn package_script_option(&self) -> Option<Path> {
let maybe_path = self.start_dir.join("pkg.rs");
debug!("package_script_option: checking whether {} exists", maybe_path.display());
- if os::path_exists(&maybe_path) {
+ if maybe_path.exists() {
Some(maybe_path)
} else {
None
let prefix = self.start_dir.component_iter().len();
debug!("Matching against {}", self.id.short_name);
- do os::walk_dir(&self.start_dir) |pth| {
+ do file::walk_dir(&self.start_dir) |pth| {
let maybe_known_crate_set = match pth.filename_str() {
Some(filename) if filter(filename) => match filename {
"lib.rs" => Some(&mut self.libs),
use std::libc;
use std::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR};
-use std::os::mkdir_recursive;
use std::os;
+use std::rt::io;
+use std::rt::io::file;
use messages::*;
pub fn default_workspace() -> Path {
fail!("Empty RUST_PATH");
}
let result = p[0];
- if !os::path_is_dir(&result) {
- os::mkdir_recursive(&result, U_RWX);
+ if !result.is_dir() {
+ file::mkdir_recursive(&result, io::UserRWX);
}
result
}
/// Creates a directory that is readable, writeable,
/// and executable by the user. Returns true iff creation
/// succeeded.
-pub fn make_dir_rwx(p: &Path) -> bool { os::make_dir(p, U_RWX) }
+pub fn make_dir_rwx(p: &Path) -> bool {
+ io::result(|| file::mkdir(p, io::UserRWX)).is_ok()
+}
-pub fn make_dir_rwx_recursive(p: &Path) -> bool { os::mkdir_recursive(p, U_RWX) }
+pub fn make_dir_rwx_recursive(p: &Path) -> bool {
+ io::result(|| file::mkdir_recursive(p, io::UserRWX)).is_ok()
+}
// n.b. The next three functions ignore the package version right
// now. Should fix that.
pub fn workspace_contains_package_id_(pkgid: &PkgId, workspace: &Path,
// Returns the directory it was actually found in
workspace_to_src_dir: &fn(&Path) -> Path) -> Option<Path> {
- if !os::path_is_dir(workspace) {
+ if !workspace.is_dir() {
return None;
}
let src_dir = workspace_to_src_dir(workspace);
+ if !src_dir.is_dir() { return None }
let mut found = None;
- do os::walk_dir(&src_dir) |p| {
- if os::path_is_dir(p) {
+ do file::walk_dir(&src_dir) |p| {
+ if p.is_dir() {
if *p == src_dir.join(&pkgid.path) || {
let pf = p.filename_str();
do pf.iter().any |&g| {
result = mk_output_path(Main, Build, pkgid, result);
debug!("built_executable_in_workspace: checking whether {} exists",
result.display());
- if os::path_exists(&result) {
+ if result.exists() {
Some(result)
}
else {
result = mk_output_path(what, Build, pkgid, result);
debug!("output_in_workspace: checking whether {} exists",
result.display());
- if os::path_exists(&result) {
+ if result.exists() {
Some(result)
}
else {
fn library_in(short_name: &str, version: &Version, dir_to_search: &Path) -> Option<Path> {
debug!("Listing directory {}", dir_to_search.display());
- let dir_contents = os::list_dir(dir_to_search);
+ let dir_contents = do io::ignore_io_error { file::readdir(dir_to_search) };
debug!("dir has {:?} entries", dir_contents.len());
let lib_prefix = format!("{}{}", os::consts::DLL_PREFIX, short_name);
/// As a side effect, creates the lib-dir if it doesn't exist
pub fn target_library_in_workspace(pkgid: &PkgId, workspace: &Path) -> Path {
use conditions::bad_path::cond;
- if !os::path_is_dir(workspace) {
+ if !workspace.is_dir() {
cond.raise(((*workspace).clone(),
format!("Workspace supplied to target_library_in_workspace \
is not a directory! {}", workspace.display())));
(Install, Lib) => target_lib_dir(workspace),
(Install, _) => target_bin_dir(workspace)
};
- if !os::path_exists(&result) && !mkdir_recursive(&result, U_RWX) {
+ if io::result(|| file::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)));
/// Return the directory for <pkgid>'s build artifacts in <workspace>.
/// Creates it if it doesn't exist.
pub fn build_pkg_id_in_workspace(pkgid: &PkgId, workspace: &Path) -> Path {
- use conditions::bad_path::cond;
-
let mut result = target_build_dir(workspace);
result.push(&pkgid.path);
debug!("Creating build dir {} for package id {}", result.display(),
pkgid.to_str());
- if os::path_exists(&result) || os::mkdir_recursive(&result, U_RWX) {
- result
- }
- else {
- cond.raise((result, format!("Could not create directory for package {}", pkgid.to_str())))
- }
+ file::mkdir_recursive(&result, io::UserRWX);
+ return result;
}
/// Return the output file for a given directory name,
pub fn uninstall_package_from(workspace: &Path, pkgid: &PkgId) {
let mut did_something = false;
let installed_bin = target_executable_in_workspace(pkgid, workspace);
- if os::path_exists(&installed_bin) {
- os::remove_file(&installed_bin);
+ if installed_bin.exists() {
+ file::unlink(&installed_bin);
did_something = true;
}
let installed_lib = target_library_in_workspace(pkgid, workspace);
- if os::path_exists(&installed_lib) {
- os::remove_file(&installed_lib);
+ if installed_lib.exists() {
+ file::unlink(&installed_lib);
did_something = true;
}
if !did_something {
fn dir_has_file(dir: &Path, file: &str) -> bool {
assert!(dir.is_absolute());
- os::path_exists(&dir.join(file))
+ dir.join(file).exists()
}
pub fn find_dir_using_rust_path_hack(p: &PkgId) -> Option<Path> {
// Utils for working with version control repositories. Just git right now.
-use std::{os, run, str};
+use std::{run, str};
use std::run::{ProcessOutput, ProcessOptions, Process};
+use std::rt::io::file;
use extra::tempfile::TempDir;
use version::*;
use path_util::chmod_read_only;
/// directory (that the callee may use, for example, to check out remote sources into).
/// Returns `CheckedOutSources` if the clone succeeded.
pub fn safe_git_clone(source: &Path, v: &Version, target: &Path) -> CloneResult {
- if os::path_exists(source) {
+ if source.exists() {
debug!("{} exists locally! Cloning it into {}",
source.display(), target.display());
// Ok to use target here; we know it will succeed
- assert!(os::path_is_dir(source));
+ assert!(source.is_dir());
assert!(is_git_dir(source));
- if !os::path_exists(target) {
+ if !target.exists() {
debug!("Running: git clone {} {}", source.display(), target.display());
// FIXME (#9639): This needs to handle non-utf8 paths
let outp = run::process_output("git", [~"clone",
pub fn make_read_only(target: &Path) {
// Now, make all the files in the target dir read-only
- do os::walk_dir(target) |p| {
- if !os::path_is_dir(p) {
+ do file::walk_dir(target) |p| {
+ if !p.is_dir() {
assert!(chmod_read_only(p));
};
true
}
pub fn is_git_dir(p: &Path) -> bool {
- os::path_is_dir(&p.join(".git"))
+ p.join(".git").is_dir()
}
use context::{BuildContext, Context, RustcFlags};
use std::{os, run, str, task};
use std::rt::io;
-use std::rt::io::Writer;
-use std::rt::io::file::FileInfo;
+use std::rt::io::file;
use extra::arc::Arc;
use extra::arc::RWArc;
use extra::tempfile::TempDir;
use package_id::{PkgId};
use version::{ExactRevision, NoVersion, Version, Tagged};
use path_util::{target_executable_in_workspace, target_test_in_workspace,
- target_bench_in_workspace, make_dir_rwx, U_RWX,
+ target_bench_in_workspace, make_dir_rwx,
library_in_workspace, installed_library_in_workspace,
built_bench_in_workspace, built_test_in_workspace,
built_library_in_workspace, built_executable_in_workspace, target_build_dir,
}
fn writeFile(file_path: &Path, contents: &str) {
- let mut out = file_path.open_writer(io::CreateOrTruncate);
+ let mut out = file::create(file_path);
out.write(contents.as_bytes());
out.write(['\n' as u8]);
}
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");
- assert!(os::mkdir_recursive(&package_dir, U_RWX));
+ file::mkdir_recursive(&package_dir, io::UserRWX);
workspace
}
// 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())]);
- assert!(os::mkdir_recursive(&package_dir, U_RWX));
+ file::mkdir_recursive(&package_dir, io::UserRWX);
package_dir
}
version.to_str())]);
debug!("Created {} and does it exist? {:?}", package_dir.display(),
- os::path_is_dir(&package_dir));
+ package_dir.is_dir());
// Create main, lib, test, and bench files
debug!("mk_workspace: creating {}", package_dir.display());
- assert!(os::mkdir_recursive(&package_dir, U_RWX));
+ file::mkdir_recursive(&package_dir, io::UserRWX);
debug!("Created {} and does it exist? {:?}", package_dir.display(),
- os::path_is_dir(&package_dir));
+ package_dir.is_dir());
// Create main, lib, test, and bench files
writeFile(&package_dir.join("main.rs"),
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();
- assert!(os::mkdir_recursive(&work_dir, U_RWX));
+ file::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()));
fn is_rwx(p: &Path) -> bool {
use std::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR};
- match p.get_mode() {
- None => return false,
- Some(m) =>
- ((m & S_IRUSR as uint) == S_IRUSR as uint
- && (m & S_IWUSR as uint) == S_IWUSR as uint
- && (m & S_IXUSR as uint) == S_IXUSR as uint)
- }
+ if !p.exists() { return false }
+ let m = p.stat().mode;
+ (m & S_IRUSR as u64) == S_IRUSR as u64
+ && (m & S_IWUSR as u64) == S_IWUSR as u64
+ && (m & S_IXUSR as u64) == S_IXUSR as u64
}
fn is_read_only(p: &Path) -> bool {
use std::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR};
- match p.get_mode() {
- None => return false,
- Some(m) =>
- ((m & S_IRUSR as uint) == S_IRUSR as uint
- && (m & S_IWUSR as uint) == 0 as uint
- && (m & S_IXUSR as uint) == 0 as uint)
- }
+ if !p.exists() { return false }
+ let m = p.stat().mode;
+ (m & S_IRUSR as u64) == S_IRUSR as u64
+ && (m & S_IWUSR as u64) == 0 as u64
+ && (m & S_IXUSR as u64) == 0 as u64
}
fn test_sysroot() -> Path {
None => ~""
};
debug!("{} cd {}; {} {}", env_str, cwd.display(), cmd, args.connect(" "));
- assert!(os::path_is_dir(&*cwd));
+ assert!(cwd.is_dir());
let cwd = (*cwd).clone();
let mut prog = run::Process::new(cmd, args, run::ProcessOptions {
env: env.map(|e| e + os::env()),
let package_dir = pkgdir.join_many([~"src", pkgid.to_str()]);
// Create main, lib, test, and bench files
- assert!(os::mkdir_recursive(&package_dir, U_RWX));
+ file::mkdir_recursive(&package_dir, io::UserRWX);
debug!("Created {} and does it exist? {:?}", package_dir.display(),
- os::path_is_dir(&package_dir));
+ package_dir.is_dir());
// Create main, lib, test, and bench files
writeFile(&package_dir.join("main.rs"),
debug!("assert_lib_exists: checking whether {:?} exists", lib);
lib.is_some() && {
let libname = lib.get_ref();
- os::path_exists(libname) && is_rwx(libname)
+ libname.exists() && is_rwx(libname)
}
}
fn executable_exists(repo: &Path, short_name: &str) -> bool {
debug!("executable_exists: repo = {}, short_name = {}", repo.display(), short_name);
let exec = target_executable_in_workspace(&PkgId::new(short_name), repo);
- os::path_exists(&exec) && is_rwx(&exec)
+ exec.exists() && is_rwx(&exec)
}
fn test_executable_exists(repo: &Path, short_name: &str) -> bool {
debug!("test_executable_exists: repo = {}, short_name = {}", repo.display(), short_name);
let exec = built_test_in_workspace(&PkgId::new(short_name), repo);
do exec.map_default(false) |exec| {
- os::path_exists(&exec) && is_rwx(&exec)
+ exec.exists() && is_rwx(&exec)
}
}
fn remove_executable_file(p: &PkgId, workspace: &Path) {
let exec = target_executable_in_workspace(&PkgId::new(p.short_name), workspace);
- if os::path_exists(&exec) {
- assert!(os::remove_file(&exec));
+ if exec.exists() {
+ file::unlink(&exec);
}
}
let exec = built_executable_in_workspace(&PkgId::new(short_name), repo);
exec.is_some() && {
let execname = exec.get_ref();
- os::path_exists(execname) && is_rwx(execname)
+ execname.exists() && is_rwx(execname)
}
}
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) => assert!(os::remove_file(&r)),
+ Some(r) => file::unlink(&r),
None => ()
}
}
}
fn file_exists(repo: &Path, short_name: &str, extension: &str) -> bool {
- os::path_exists(&target_build_dir(repo).join_many([short_name.to_owned(),
- format!("{}.{}", short_name, extension)]))
+ target_build_dir(repo).join_many([short_name.to_owned(),
+ format!("{}.{}", short_name, extension)])
+ .exists()
}
fn assert_built_library_exists(repo: &Path, short_name: &str) {
let lib = built_library_in_workspace(&PkgId::new(short_name), repo);
lib.is_some() && {
let libname = lib.get_ref();
- os::path_exists(libname) && is_rwx(libname)
+ libname.exists() && is_rwx(libname)
}
}
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 = os::list_dir_path(&pkg_src_dir);
+ let contents = file::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
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 = os::list_dir_path(&pkg_src_dir);
+ let contents = file::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
let mut maybe_p = None;
let maybe_file = pkg_src_dir.join(filename);
debug!("Trying to frob {} -- {}", pkg_src_dir.display(), filename);
- if os::path_exists(&maybe_file) {
+ if maybe_file.exists() {
maybe_p = Some(maybe_file);
}
debug!("Frobbed? {:?}", maybe_p);
do io::io_error::cond.trap(|e| {
cond.raise((p.clone(), format!("Bad path: {}", e.desc)));
}).inside {
- let mut w = p.open_writer(io::Append);
+ let mut w = file::open_stream(p, io::Append, io::Write);
w.write(bytes!("/* hi */\n"));
}
}
fn test_make_dir_rwx() {
let temp = &os::tmpdir();
let dir = temp.join("quux");
- assert!(!os::path_exists(&dir) ||
- os::remove_dir_recursive(&dir));
+ if dir.exists() {
+ file::rmdir_recursive(&dir);
+ }
debug!("Trying to make {}", dir.display());
assert!(make_dir_rwx(&dir));
- assert!(os::path_is_dir(&dir));
+ assert!(dir.is_dir());
assert!(is_rwx(&dir));
- assert!(os::remove_dir_recursive(&dir));
+ file::rmdir_recursive(&dir);
}
// n.b. I ignored the next two tests for now because something funny happens on linux
// Check that all files exist
let exec = target_executable_in_workspace(&temp_pkg_id, temp_workspace);
debug!("exec = {}", exec.display());
- assert!(os::path_exists(&exec));
+ assert!(exec.exists());
assert!(is_rwx(&exec));
let lib = installed_library_in_workspace(&temp_pkg_id.path, temp_workspace);
debug!("lib = {:?}", lib);
- assert!(lib.as_ref().map_default(false, |l| os::path_exists(l)));
+ assert!(lib.as_ref().map_default(false, |l| l.exists()));
assert!(lib.as_ref().map_default(false, |l| is_rwx(l)));
// And that the test and bench executables aren't installed
- assert!(!os::path_exists(&target_test_in_workspace(&temp_pkg_id, temp_workspace)));
+ assert!(!target_test_in_workspace(&temp_pkg_id, temp_workspace).exists());
let bench = target_bench_in_workspace(&temp_pkg_id, temp_workspace);
debug!("bench = {}", bench.display());
- assert!(!os::path_exists(&bench));
+ assert!(!bench.exists());
// Make sure the db isn't dirty, so that it doesn't try to save()
// asynchronously after the temporary directory that it wants to save
// Check that all files exist
let exec = target_executable_in_workspace(&temp_pkg_id, temp_workspace);
debug!("exec = {}", exec.display());
- assert!(os::path_exists(&exec));
+ assert!(exec.exists());
assert!(is_rwx(&exec));
let lib = installed_library_in_workspace(&temp_pkg_id.path, temp_workspace);
debug!("lib = {:?}", lib);
- assert!(lib.as_ref().map_default(false, |l| os::path_exists(l)));
+ assert!(lib.as_ref().map_default(false, |l| l.exists()));
assert!(lib.as_ref().map_default(false, |l| is_rwx(l)));
// And that the test and bench executables aren't installed
- assert!(!os::path_exists(&target_test_in_workspace(&temp_pkg_id, temp_workspace)));
+ assert!(!target_test_in_workspace(&temp_pkg_id, temp_workspace).exists());
let bench = target_bench_in_workspace(&temp_pkg_id, temp_workspace);
debug!("bench = {}", bench.display());
- assert!(!os::path_exists(&bench));
+ assert!(!bench.exists());
}
debug!("Checking for files in {}", ws.display());
let exec = target_executable_in_workspace(&temp_pkg_id, &ws);
debug!("exec = {}", exec.display());
- assert!(os::path_exists(&exec));
+ assert!(exec.exists());
assert!(is_rwx(&exec));
let _built_lib =
built_library_in_workspace(&temp_pkg_id,
assert_lib_exists(&ws, &temp_pkg_id.path, temp_pkg_id.version.clone());
let built_test = built_test_in_workspace(&temp_pkg_id,
&ws).expect("test_install_git: built test should exist");
- assert!(os::path_exists(&built_test));
+ assert!(built_test.exists());
let built_bench = built_bench_in_workspace(&temp_pkg_id,
&ws).expect("test_install_git: built bench should exist");
- assert!(os::path_exists(&built_bench));
+ assert!(built_bench.exists());
// And that the test and bench executables aren't installed
let test = target_test_in_workspace(&temp_pkg_id, &ws);
- assert!(!os::path_exists(&test));
+ assert!(!test.exists());
debug!("test = {}", test.display());
let bench = target_bench_in_workspace(&temp_pkg_id, &ws);
debug!("bench = {}", bench.display());
- assert!(!os::path_exists(&bench));
+ assert!(!bench.exists());
}
#[test]
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);
writeFile(&repo_subdir.join("main.rs"),
"fn main() { let _x = (); }");
writeFile(&repo_subdir.join("lib.rs"),
let mut dir = target_build_dir(&repo.join(".rust"));
dir.push(&Path::new("src/mockgithub.com/catamorphism/test_pkg_version-0.3"));
debug!("dir = {}", dir.display());
- assert!(os::path_is_dir(&dir));
- assert!(os::path_exists(&dir.join("version-0.3-file.txt")));
- assert!(!os::path_exists(&dir.join("version-0.4-file.txt")));
+ assert!(dir.is_dir());
+ assert!(dir.join("version-0.3-file.txt").exists());
+ assert!(!dir.join("version-0.4-file.txt").exists());
}
#[test]
let source = Path::new(file!()).dir_path().join_many(
[~"testsuite", ~"pass", ~"src", ~"fancy-lib", ~"pkg.rs"]);
debug!("package_script_with_default_build: {}", source.display());
- if !os::copy_file(&source,
- &dir.join_many(["src", "fancy-lib-0.1", "pkg.rs"])) {
- fail!("Couldn't copy file");
- }
+ file::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!(os::path_exists(&target_build_dir(dir).join_many([~"fancy-lib", ~"generated.rs"])));
+ assert!(target_build_dir(dir).join_many([~"fancy-lib", ~"generated.rs"]).exists());
let generated_path = target_build_dir(dir).join_many([~"fancy-lib", ~"generated.rs"]);
debug!("generated path = {}", generated_path.display());
- assert!(os::path_exists(&generated_path));
+ assert!(generated_path.exists());
}
#[test]
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"]);
- assert!(os::mkdir_recursive(&package_dir, U_RWX));
+ file::mkdir_recursive(&package_dir, io::UserRWX);
writeFile(&package_dir.join("main.rs"),
"fn main() { let _x = (); }");
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"]);
- assert!(os::mkdir_recursive(&package_dir, U_RWX));
+ file::mkdir_recursive(&package_dir, io::UserRWX);
writeFile(&package_dir.join("lib.rs"),
"fn main() { let _x = (); }");
debug!("install_no_arg: dir = {}", package_dir.display());
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"]);
- assert!(os::mkdir_recursive(&package_dir, U_RWX));
+ file::mkdir_recursive(&package_dir, io::UserRWX);
writeFile(&package_dir.join("main.rs"),
"fn main() { let _x = (); }");
assert_built_executable_exists(&tmp, "foo");
command_line_test([~"clean"], &package_dir);
let res = built_executable_in_workspace(&PkgId::new("foo"), &tmp);
- assert!(!res.as_ref().map_default(false, |m| { os::path_exists(m) }));
+ assert!(!res.as_ref().map_default(false, |m| m.exists()));
}
#[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"]);
- assert!(os::mkdir_recursive(&abc.join(".rust"), U_RWX));
- assert!(os::mkdir_recursive(&abc.with_filename(".rust"), U_RWX));
- assert!(os::mkdir_recursive(&abc.dir_path().with_filename(".rust"), U_RWX));
+ 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);
assert!(os::change_dir(abc));
let p = rust_path();
temp_pkg_id.path.as_str().unwrap())], repo);
let file1 = repo.join_many(["mockgithub.com", "catamorphism", "test-pkg", "testbranch_only"]);
let file2 = repo.join_many(["mockgithub.com", "catamorphism", "test-pkg", "master_only"]);
- assert!(os::path_exists(&file1));
- assert!(!os::path_exists(&file2));
+ assert!(file1.exists());
+ assert!(!file2.exists());
}
#[test]
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"]);
- assert!(os::mkdir_recursive(&aux_dir, U_RWX));
+ file::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");
- assert!(os::path_exists(&aux_pkg_file));
+ assert!(aux_pkg_file.exists());
writeFile(&main_file,
"extern mod test = \"mockgithub.com/catamorphism/test_pkg\";\nuse test::bar;\
str::from_utf8(outp.output),
str::from_utf8(outp.error));
}
- assert!(os::path_exists(&exec_file) && is_executable(&exec_file));
+ assert!(exec_file.exists() && is_executable(&exec_file));
}
#[test]
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"]);
- assert!(os::mkdir_recursive(&aux_dir, U_RWX));
+ file::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");
- assert!(os::path_exists(&aux_pkg_file));
+ assert!(aux_pkg_file.exists());
writeFile(&main_file,
"extern mod test = \"rust-awesomeness\";\nuse test::bar;\
str::from_utf8(outp.output),
str::from_utf8(outp.error));
}
- assert!(os::path_exists(&exec_file) && is_executable(&exec_file));
+ assert!(exec_file.exists() && is_executable(&exec_file));
}
#[test]
"extern mod rustpkg; fn main() {}");
command_line_test([~"build", ~"foo"], workspace);
debug!("workspace = {}", workspace.display());
- assert!(os::path_exists(&target_build_dir(workspace).join("foo").join(format!("pkg{}",
- os::EXE_SUFFIX))));
+ assert!(target_build_dir(workspace).join("foo").join(format!("pkg{}",
+ os::EXE_SUFFIX)).exists());
}
#[test]
"extern mod rustpkg; fn main() { debug!(\"Hi\"); }");
command_line_test([~"build", ~"foo"], workspace);
debug!("workspace = {}", workspace.display());
- assert!(os::path_exists(&target_build_dir(workspace).join("foo").join(format!("pkg{}",
- os::EXE_SUFFIX))));
+ assert!(target_build_dir(workspace).join("foo").join(format!("pkg{}",
+ os::EXE_SUFFIX)).exists());
}
#[test]
// 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");
- assert!(os::mkdir_recursive(&cwd, U_RWX));
+ file::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");
// 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"]);
- assert!(os::mkdir_recursive(&subdir, U_RWX));
+ file::mkdir_recursive(&subdir, io::UserRWX);
writeFile(&subdir.join("lib.rs"), "pub fn f() { }");
let name = ~"foo/bar/quux";
// 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();
- assert!(os::mkdir_recursive(&workspace.join_many(["src", "mockgithub.com",
- "mozilla", "some_repo"]), U_RWX));
+ file::mkdir_recursive(&workspace.join_many(["src", "mockgithub.com",
+ "mozilla", "some_repo"]),
+ io::UserRWX);
let foo_dir = workspace.join_many(["src", "mockgithub.com", "mozilla", "some_repo",
"extras", "foo"]);
let bar_dir = workspace.join_many(["src", "mockgithub.com", "mozilla", "some_repo",
"extras", "bar"]);
- assert!(os::mkdir_recursive(&foo_dir, U_RWX));
- assert!(os::mkdir_recursive(&bar_dir, U_RWX));
+ file::mkdir_recursive(&foo_dir, io::UserRWX);
+ file::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"]);
- assert!(os::mkdir_recursive(&testpkg_dir, U_RWX));
+ file::mkdir_recursive(&testpkg_dir, io::UserRWX);
writeFile(&testpkg_dir.join("main.rs"),
"extern mod foo = \"mockgithub.com/mozilla/some_repo/extras/foo\";\n
~"build",
~"foo"],
workspace);
- assert!(os::path_is_dir(&target_build_dir(workspace)));
+ assert!(target_build_dir(workspace).is_dir());
assert!(built_executable_exists(workspace, "foo"));
- assert!(os::list_dir(&workspace.join("build")).len() == 1);
+ assert!(file::readdir(&workspace.join("build")).len() == 1);
}
#[test]
~"install",
~"foo"],
workspace);
- assert!(os::path_is_dir(&workspace.join_many([~"lib", host_triple()])));
+ assert!(workspace.join_many([~"lib", host_triple()]).is_dir());
assert_lib_exists(workspace, &Path::new("foo"), NoVersion);
- assert!(os::list_dir(&workspace.join("lib")).len() == 1);
- assert!(os::path_is_dir(&workspace.join("bin")));
+ assert!(file::readdir(&workspace.join("lib")).len() == 1);
+ assert!(workspace.join("bin").is_dir());
assert_executable_exists(workspace, "foo");
}
let workspace = workspace.path();
let b_dir = workspace.join_many(["src", "b-0.1"]);
let b_subdir = b_dir.join("test");
- assert!(os::mkdir_recursive(&b_subdir, U_RWX));
+ file::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);
debug!("Checking for files in {}", ws.display());
let exec = target_executable_in_workspace(&temp_pkg_id, &ws);
debug!("exec = {}", exec.display());
- assert!(os::path_exists(&exec));
+ assert!(exec.exists());
assert!(is_rwx(&exec));
let built_lib =
built_library_in_workspace(&temp_pkg_id,
&ws).expect("test_install_git: built lib should exist");
- assert!(os::path_exists(&built_lib));
+ assert!(built_lib.exists());
assert!(is_rwx(&built_lib));
// Make sure sources are (a) under "build" and (b) read-only
let src1 = target_build_dir(&ws).join_many([~"src", temp_pkg_id.to_str(), ~"main.rs"]);
let src2 = target_build_dir(&ws).join_many([~"src", temp_pkg_id.to_str(), ~"lib.rs"]);
- assert!(os::path_exists(&src1));
- assert!(os::path_exists(&src2));
+ assert!(src1.exists());
+ assert!(src2.exists());
assert!(is_read_only(&src1));
assert!(is_read_only(&src2));
}
debug!("repo = {}", repo.display());
let repo_subdir = repo.join_many(["mockgithub.com", "catamorphism", "test-pkg"]);
debug!("repo_subdir = {}", repo_subdir.display());
- assert!(os::mkdir_recursive(&repo.join_many([".rust", "src"]), U_RWX));
+ file::mkdir_recursive(&repo.join_many([".rust", "src"]), io::UserRWX);
writeFile(&repo_subdir.join("main.rs"),
"fn main() { let _x = (); }");
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");
- os::mkdir_recursive(&source_dir, U_RWX);
+ file::mkdir_recursive(&source_dir, io::UserRWX);
writeFile(&source_dir.join("main.rs"),
"fn main() { let _x = (); }");
command_line_test([~"install", ~"foo"], &source_dir);
debug!("dir = {}", dir.display());
let source = Path::new(file!()).dir_path().join_many(
[~"testsuite", ~"pass", ~"src", ~"c-dependencies", ~"pkg.rs"]);
- if !os::copy_file(&source,
- &dir.join_many([~"src", ~"cdep-0.1", ~"pkg.rs"])) {
- fail!("Couldn't copy file");
- }
+ file::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");
let c_library_path = out_dir.join(platform_library_name("foo"));
debug!("c library path: {}", c_library_path.display());
- assert!(os::path_exists(&c_library_path));
+ assert!(c_library_path.exists());
}
#[test]
debug!("dir = {}", dir.display());
let source = Path::new(file!()).dir_path().join_many(
[~"testsuite", ~"pass", ~"src", ~"c-dependencies", ~"pkg.rs"]);
- if !os::copy_file(&source,
- &dir.join_many([~"src", ~"cdep-0.1", ~"pkg.rs"])) {
- fail!("Couldn't copy file");
- }
+ file::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");
let c_library_path = out_dir.join(platform_library_name("foo"));
debug!("c library path: {}", c_library_path.display());
- assert!(os::path_exists(&c_library_path));
+ assert!(c_library_path.exists());
// Now, make it read-only so rebuilding will fail
assert!(chmod_read_only(&c_library_path));
[~"testsuite", ~"pass", ~"src", ~"c-dependencies", ~"pkg.rs"]);
let target = dir.join_many([~"src", ~"cdep-0.1", ~"pkg.rs"]);
debug!("Copying {} -> {}", source.display(), target.display());
- if !os::copy_file(&source, &target) {
- fail!("Couldn't copy file");
- }
+ file::copy(&source, &target);
command_line_test([~"build", ~"cdep"], dir);
assert_executable_exists(dir, "cdep");
let out_dir = target_build_dir(dir).join("cdep");
let c_library_path = out_dir.join(platform_library_name("foo"));
debug!("c library path: {}", c_library_path.display());
- assert!(os::path_exists(&c_library_path));
+ assert!(c_library_path.exists());
// Now, make the Rust library read-only so rebuilding will fail
match built_library_in_workspace(&PkgId::new("cdep"), dir) {
fn is_executable(p: &Path) -> bool {
use std::libc::consts::os::posix88::{S_IXUSR};
- match p.get_mode() {
- None => false,
- Some(mode) => mode & S_IXUSR as uint == S_IXUSR as uint
- }
+ p.exists() && p.stat().mode & S_IXUSR as u64 == S_IXUSR as u64
}
let sysroot_arg = args[1].clone();
let sysroot = Path::new(sysroot_arg);
- if !os::path_exists(&sysroot) {
+ if !sysroot.exists() {
fail!("Package script requires a sysroot that exists; {} doesn't", sysroot.display());
}
extern mod rustc;
use std::os;
-use std::rt::io;
-use std::rt::io::Writer;
-use std::rt::io::file::FileInfo;
+use std::rt::io::file;
use rustpkg::api;
use rustpkg::version::NoVersion;
let sysroot_arg = args[1].clone();
let sysroot = Path::new(sysroot_arg);
- if !os::path_exists(&sysroot) {
+ if !sysroot.exists() {
debug!("Failing, sysroot");
fail!("Package script requires a sysroot that exists;{} doesn't", sysroot.display());
}
let out_path = os::self_exe_path().expect("Couldn't get self_exe path");
debug!("Writing file");
- let mut file = out_path.join("generated.rs").open_writer(io::Create);
+ let mut file = file::create(&out_path.join("generated.rs"));
file.write("pub fn wheeeee() { let xs = [1, 2, 3]; \
for _ in xs.iter() { assert!(true); } }".as_bytes());
use std::libc;
use std::os;
+use std::rt::io;
+use std::rt::io::file;
use extra::workcache;
use rustc::driver::{driver, session};
use extra::getopts::groups::getopts;
pub use target::{OutputType, Main, Lib, Bench, Test, JustOne, lib_name_of, lib_crate_filename};
pub use target::{Target, Build, Install};
use extra::treemap::TreeMap;
-use path_util::U_RWX;
pub use target::{lib_name_of, lib_crate_filename, WhatToBuild, MaybeCustom, Inferred};
use workcache_support::{digest_file_with_date, digest_only_date};
let mut out_dir = target_build_dir(workspace);
out_dir.push(&pkg_id.path);
// Make the output directory if it doesn't exist already
- assert!(os::mkdir_recursive(&out_dir, U_RWX));
+ file::mkdir_recursive(&out_dir, io::UserRWX);
let binary = os::args()[0].to_managed();
// Make sure all the library directories actually exist, since the linker will complain
// otherwise
for p in addl_lib_search_paths.iter() {
- if os::path_exists(p) {
- assert!(os::path_is_dir(p));
+ if p.exists() {
+ assert!(p.is_dir())
}
else {
- assert!(os::mkdir_recursive(p, U_RWX));
+ file::mkdir_recursive(p, io::UserRWX);
}
}
};
for p in discovered_output.iter() {
debug!("About to discover output {}", p.display());
- if os::path_exists(p) {
+ if p.exists() {
debug!("4. discovering output {}", p.display());
// FIXME (#9639): This needs to handle non-utf8 paths
exec.discover_output("binary", p.as_str().unwrap(), digest_only_date(p));
/// 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.modified);
- debug!("Date = {:?}", out);
- out.map(|t| { t as libc::time_t })
+ debug!("Scrutinizing datestamp for {} - does it exist? {:?}", p.display(),
+ p.exists());
+ match io::result(|| p.stat()) {
+ Ok(s) => {
+ let out = s.modified;
+ debug!("Date = {:?}", out);
+ Some(out as libc::time_t)
+ }
+ Err(*) => None,
+ }
}
pub type DepMap = TreeMap<~str, ~[(~str, ~str)]>;
extern mod std;
use extra::semver;
-use std::{char, os, result, run, str};
+use std::{char, result, run, str};
use extra::tempfile::TempDir;
use path_util::rust_path;
for rp in rustpath.iter() {
let local_path = rp.join(local_path);
let git_dir = local_path.join(".git");
- if !os::path_is_dir(&git_dir) {
+ if !git_dir.is_dir() {
continue;
}
// FIXME (#9639): This needs to handle non-utf8 paths
// except according to those terms.
use std::rt::io;
-use std::rt::io::Reader;
-use std::rt::io::file::FileInfo;
+use std::rt::io::file;
use extra::workcache;
use sha1::{Digest, Sha1};
/// Hashes the file contents along with the last-modified time
pub fn digest_file_with_date(path: &Path) -> ~str {
use conditions::bad_path::cond;
- use cond1 = conditions::bad_stat::cond;
- let mut err = None;
- let bytes = do io::io_error::cond.trap(|e| err = Some(e)).inside {
- path.open_reader(io::Open).read_to_end()
- };
- match err {
- None => {
+ match io::result(|| file::open(path).read_to_end()) {
+ Ok(bytes) => {
let mut sha = Sha1::new();
sha.input(bytes);
- let st = match path.stat() {
- Some(st) => st,
- None => cond1.raise((path.clone(), format!("Couldn't get file access time")))
- };
+ let st = path.stat();
sha.input_str(st.modified.to_str());
sha.result_str()
}
- Some(e) => {
+ Err(e) => {
cond.raise((path.clone(), format!("Couldn't read file: {}", e.desc)));
~""
}
/// Hashes only the last-modified time
pub fn digest_only_date(path: &Path) -> ~str {
- use cond = conditions::bad_stat::cond;
-
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")))
- };
+ let st = path.stat();
sha.input_str(st.modified.to_str());
sha.result_str()
}
}
pub fn is_workspace(p: &Path) -> bool {
- os::path_is_dir(&p.join("src"))
+ p.join("src").is_dir()
}
/// Construct a workspace and package-ID name based on the current directory.
self.sync_cleanup(result)
}
- pub fn mkdir(self, loop_: &Loop, path: &CString, mode: int, cb: FsCallback) {
+ pub fn mkdir(self, loop_: &Loop, path: &CString, mode: c_int, cb: FsCallback) {
let complete_cb_ptr = {
let mut me = self;
me.req_boilerplate(Some(cb))
assert_eq!(ret, 0);
}
+ pub fn chmod(self, loop_: &Loop, path: &CString, mode: c_int, cb: FsCallback) {
+ let complete_cb_ptr = {
+ let mut me = self;
+ me.req_boilerplate(Some(cb))
+ };
+ let ret = path.with_ref(|p| unsafe {
+ uvll::fs_chmod(loop_.native_handle(), self.native_handle(), p, mode,
+ complete_cb_ptr)
+ });
+ assert_eq!(ret, 0);
+ }
+
pub fn readdir(self, loop_: &Loop, path: &CString,
flags: c_int, cb: FsCallback) {
let complete_cb_ptr = {
S_IRUSR;
let mkdir_req = FsRequest::new();
do mkdir_req.mkdir(&loop_, &path.to_c_str(),
- mode as int) |req,uverr| {
+ mode as c_int) |req,uverr| {
assert!(uverr.is_none());
let loop_ = req.get_loop();
let stat_req = FsRequest::new();
let mode = S_IWUSR |
S_IRUSR;
let mkdir_req = FsRequest::new();
- do mkdir_req.mkdir(&loop_, &path.to_c_str(), mode as int) |req,uverr| {
+ do mkdir_req.mkdir(&loop_, &path.to_c_str(), mode as c_int) |req,uverr| {
assert!(uverr.is_none());
let loop_ = req.get_loop();
let mkdir_req = FsRequest::new();
do mkdir_req.mkdir(&loop_, &path.to_c_str(),
- mode as int) |req,uverr| {
+ mode as c_int) |req,uverr| {
assert!(uverr.is_some());
let loop_ = req.get_loop();
let _stat = req.get_stat();
use std::ptr;
use std::str;
use std::result::*;
+use std::rt::io;
use std::rt::io::IoError;
use std::rt::io::net::ip::{SocketAddr, IpAddr};
use std::rt::io::{standard_error, OtherIoError, SeekStyle, SeekSet, SeekCur,
use std::unstable::sync::Exclusive;
use std::path::{GenericPath, Path};
use std::libc::{lseek, off_t, O_CREAT, O_APPEND, O_TRUNC, O_RDWR, O_RDONLY,
- O_WRONLY, S_IRUSR, S_IWUSR, S_IRWXU};
+ O_WRONLY, S_IRUSR, S_IWUSR};
use std::rt::io::{FileMode, FileAccess, OpenOrCreate, Open, Create,
CreateOrTruncate, Append, Truncate, Read, Write, ReadWrite,
FileStat};
assert!(!result_cell.is_empty());
return result_cell.take();
}
- fn fs_mkdir(&mut self, path: &CString, mode: int) -> Result<(), IoError> {
+ fn fs_mkdir(&mut self, path: &CString,
+ perm: io::FilePermission) -> Result<(), IoError> {
do uv_fs_helper(self.uv_loop(), path) |mkdir_req, l, p, cb| {
- do mkdir_req.mkdir(l, p, mode) |req, err| {
+ do mkdir_req.mkdir(l, p, perm as c_int) |req, err| {
cb(req, err)
};
}
};
}
}
+ fn fs_chmod(&mut self, path: &CString,
+ perm: io::FilePermission) -> Result<(), IoError> {
+ do uv_fs_helper(self.uv_loop(), path) |chmod_req, l, p, cb| {
+ do chmod_req.chmod(l, p, perm as c_int) |req, err| {
+ cb(req, err)
+ };
+ }
+ }
+>>>>>>> Remove all blocking std::os blocking functions
fn fs_readdir(&mut self, path: &CString, flags: c_int) ->
Result<~[Path], IoError> {
use str::StrSlice;
rust_uv_fs_fstat(loop_ptr, req, fd, cb)
}
-pub unsafe fn fs_mkdir(loop_ptr: *uv_loop_t, req: *uv_fs_t, path: *c_char, mode: int,
- cb: *u8) -> c_int {
+pub unsafe fn fs_mkdir(loop_ptr: *uv_loop_t, req: *uv_fs_t, path: *c_char,
+ mode: c_int, cb: *u8) -> c_int {
#[fixed_stack_segment]; #[inline(never)];
rust_uv_fs_mkdir(loop_ptr, req, path, mode as c_int, cb)
rust_uv_fs_rename(loop_ptr, req, path, to, cb)
}
+pub unsafe fn fs_chmod(loop_ptr: *uv_loop_t, req: *uv_fs_t, path: *c_char,
+ mode: c_int, cb: *u8) -> c_int {
+ #[fixed_stack_segment]; #[inline(never)];
+
+ rust_uv_fs_chmod(loop_ptr, req, path, mode as c_int, cb)
+}
pub unsafe fn fs_readdir(loop_ptr: *uv_loop_t, req: *uv_fs_t, path: *c_char,
flags: c_int, cb: *u8) -> c_int {
#[fixed_stack_segment]; #[inline(never)];
cb: *u8) -> c_int;
fn rust_uv_fs_rename(loop_ptr: *c_void, req: *uv_fs_t, path: *c_char,
to: *c_char, cb: *u8) -> c_int;
+ fn rust_uv_fs_chmod(loop_ptr: *c_void, req: *uv_fs_t, path: *c_char,
+ mode: c_int, cb: *u8) -> c_int;
fn rust_uv_fs_readdir(loop_ptr: *c_void, req: *uv_fs_t, path: *c_char,
flags: c_int, cb: *u8) -> c_int;
fn rust_uv_fs_req_cleanup(req: *uv_fs_t);
#[cfg(test)]
mod tests {
- use super::*;
- use prelude::*;
+ use cmp::{Equal, Greater, Less, Eq, TotalOrd};
+ use ops::{BitAnd, BitXor, BitOr};
+ use from_str::{FromStr, from_str};
+ use option::{Some, None};
+ use super::all_values;
#[test]
fn test_bool() {
use iter::range;
use libc;
use libc::{c_char, c_void, c_int, size_t};
-use libc::FILE;
use option::{Some, None};
use os;
use prelude::*;
use unstable::finally::Finally;
use vec;
-pub use libc::fclose;
pub use os::consts::*;
/// Delegates to the libc close() function, returning the same return value.
}
}
-// On Windows, wide character version of function must be used to support
-// unicode, so functions should be split into at least two versions,
-// which are for Windows and for non-Windows, if necessary.
-// See https://github.com/mozilla/rust/issues/9822 for more information.
-
-mod rustrt {
- use libc::{c_char, c_int};
- use libc;
-
- extern {
- pub fn rust_path_is_dir(path: *libc::c_char) -> c_int;
- pub fn rust_path_exists(path: *libc::c_char) -> c_int;
- }
-
- // Uses _wstat instead of stat.
- #[cfg(windows)]
- extern {
- pub fn rust_path_is_dir_u16(path: *u16) -> c_int;
- pub fn rust_path_exists_u16(path: *u16) -> c_int;
- }
-}
-
pub static TMPBUF_SZ : uint = 1000u;
static BUF_BYTES : uint = 2048u;
_unsetenv(n);
}
-pub fn fdopen(fd: c_int) -> *FILE {
- #[fixed_stack_segment]; #[inline(never)];
- do "r".with_c_str |modebuf| {
- unsafe {
- libc::fdopen(fd, modebuf)
- }
- }
-}
-
pub struct Pipe {
input: c_int,
out: c_int
}
}
-
-
#[cfg(windows)]
pub fn pipe() -> Pipe {
#[fixed_stack_segment]; #[inline(never)];
}
}
-/// Recursively walk a directory structure
-pub fn walk_dir(p: &Path, f: &fn(&Path) -> bool) -> bool {
- let r = list_dir(p);
- r.iter().advance(|q| {
- let path = &p.join(q);
- f(path) && (!path_is_dir(path) || walk_dir(path, |p| f(p)))
- })
-}
-
-#[cfg(unix)]
-/// Indicates whether a path represents a directory
-pub fn path_is_dir(p: &Path) -> bool {
- #[fixed_stack_segment]; #[inline(never)];
- unsafe {
- do p.with_c_str |buf| {
- rustrt::rust_path_is_dir(buf) != 0 as c_int
- }
- }
-}
-
-
-#[cfg(windows)]
-pub fn path_is_dir(p: &Path) -> bool {
- #[fixed_stack_segment]; #[inline(never)];
- unsafe {
- do os::win32::as_utf16_p(p.as_str().unwrap()) |buf| {
- rustrt::rust_path_is_dir_u16(buf) != 0 as c_int
- }
- }
-}
-
-#[cfg(unix)]
-/// Indicates whether a path exists
-pub fn path_exists(p: &Path) -> bool {
- #[fixed_stack_segment]; #[inline(never)];
- unsafe {
- do p.with_c_str |buf| {
- rustrt::rust_path_exists(buf) != 0 as c_int
- }
- }
-}
-
-#[cfg(windows)]
-pub fn path_exists(p: &Path) -> bool {
- #[fixed_stack_segment]; #[inline(never)];
- unsafe {
- do os::win32::as_utf16_p(p.as_str().unwrap()) |buf| {
- rustrt::rust_path_exists_u16(buf) != 0 as c_int
- }
- }
-}
-
/**
* Convert a relative path to an absolute path
*
}
}
-
-/// Creates a directory at the specified path
-pub fn make_dir(p: &Path, mode: c_int) -> bool {
- return mkdir(p, mode);
-
- #[cfg(windows)]
- fn mkdir(p: &Path, _mode: c_int) -> bool {
- #[fixed_stack_segment]; #[inline(never)];
- unsafe {
- use os::win32::as_utf16_p;
- // FIXME: turn mode into something useful? #2623
- do as_utf16_p(p.as_str().unwrap()) |buf| {
- libc::CreateDirectoryW(buf, ptr::mut_null())
- != (0 as libc::BOOL)
- }
- }
- }
-
- #[cfg(unix)]
- fn mkdir(p: &Path, mode: c_int) -> bool {
- #[fixed_stack_segment]; #[inline(never)];
- do p.with_c_str |buf| {
- unsafe {
- libc::mkdir(buf, mode as libc::mode_t) == (0 as c_int)
- }
- }
- }
-}
-
-/// Creates a directory with a given mode.
-/// Returns true iff creation
-/// succeeded. Also creates all intermediate subdirectories
-/// if they don't already exist, giving all of them the same mode.
-
-// tjc: if directory exists but with different permissions,
-// should we return false?
-pub fn mkdir_recursive(p: &Path, mode: c_int) -> bool {
- if path_is_dir(p) {
- return true;
- }
- if p.filename().is_some() {
- let mut p_ = p.clone();
- p_.pop();
- if !mkdir_recursive(&p_, mode) {
- return false;
- }
- }
- return make_dir(p, mode);
-}
-
-/// Lists the contents of a directory
-///
-/// Each resulting Path is a relative path with no directory component.
-pub fn list_dir(p: &Path) -> ~[Path] {
- unsafe {
- #[cfg(target_os = "linux")]
- #[cfg(target_os = "android")]
- #[cfg(target_os = "freebsd")]
- #[cfg(target_os = "macos")]
- unsafe fn get_list(p: &Path) -> ~[Path] {
- #[fixed_stack_segment]; #[inline(never)];
- use libc::{dirent_t};
- use libc::{opendir, readdir, closedir};
- extern {
- fn rust_list_dir_val(ptr: *dirent_t) -> *libc::c_char;
- }
- let mut paths = ~[];
- debug!("os::list_dir -- BEFORE OPENDIR");
-
- let dir_ptr = do p.with_c_str |buf| {
- opendir(buf)
- };
-
- if (dir_ptr as uint != 0) {
- debug!("os::list_dir -- opendir() SUCCESS");
- let mut entry_ptr = readdir(dir_ptr);
- while (entry_ptr as uint != 0) {
- let cstr = CString::new(rust_list_dir_val(entry_ptr), false);
- paths.push(Path::new(cstr));
- entry_ptr = readdir(dir_ptr);
- }
- closedir(dir_ptr);
- }
- else {
- debug!("os::list_dir -- opendir() FAILURE");
- }
- debug!("os::list_dir -- AFTER -- \\#: {}", paths.len());
- paths
- }
- #[cfg(windows)]
- unsafe fn get_list(p: &Path) -> ~[Path] {
- #[fixed_stack_segment]; #[inline(never)];
- use libc::consts::os::extra::INVALID_HANDLE_VALUE;
- use libc::{wcslen, free};
- use libc::funcs::extra::kernel32::{
- FindFirstFileW,
- FindNextFileW,
- FindClose,
- };
- use libc::types::os::arch::extra::HANDLE;
- use os::win32::{
- as_utf16_p
- };
- use rt::global_heap::malloc_raw;
-
- #[nolink]
- extern {
- fn rust_list_dir_wfd_size() -> libc::size_t;
- fn rust_list_dir_wfd_fp_buf(wfd: *libc::c_void) -> *u16;
- }
- let star = p.join("*");
- do as_utf16_p(star.as_str().unwrap()) |path_ptr| {
- let mut paths = ~[];
- let wfd_ptr = malloc_raw(rust_list_dir_wfd_size() as uint);
- let find_handle = FindFirstFileW(path_ptr, wfd_ptr as HANDLE);
- if find_handle as libc::c_int != INVALID_HANDLE_VALUE {
- let mut more_files = 1 as libc::c_int;
- while more_files != 0 {
- let fp_buf = rust_list_dir_wfd_fp_buf(wfd_ptr);
- if fp_buf as uint == 0 {
- fail!("os::list_dir() failure: got null ptr from wfd");
- }
- else {
- let fp_vec = vec::from_buf(
- fp_buf, wcslen(fp_buf) as uint);
- let fp_str = str::from_utf16(fp_vec);
- paths.push(Path::new(fp_str));
- }
- more_files = FindNextFileW(find_handle, wfd_ptr as HANDLE);
- }
- FindClose(find_handle);
- free(wfd_ptr)
- }
- paths
- }
- }
- do get_list(p).move_iter().filter |path| {
- path.as_vec() != bytes!(".") && path.as_vec() != bytes!("..")
- }.collect()
- }
-}
-
-/**
- * Lists the contents of a directory
- *
- * This version prepends each entry with the directory.
- */
-pub fn list_dir_path(p: &Path) -> ~[Path] {
- list_dir(p).map(|f| p.join(f))
-}
-
-/// Removes a directory at the specified path, after removing
-/// all its contents. Use carefully!
-pub fn remove_dir_recursive(p: &Path) -> bool {
- let mut error_happened = false;
- do walk_dir(p) |inner| {
- if !error_happened {
- if path_is_dir(inner) {
- if !remove_dir_recursive(inner) {
- error_happened = true;
- }
- }
- else {
- if !remove_file(inner) {
- error_happened = true;
- }
- }
- }
- true
- };
- // Directory should now be empty
- !error_happened && remove_dir(p)
-}
-
-/// Removes a directory at the specified path
-pub fn remove_dir(p: &Path) -> bool {
- return rmdir(p);
-
- #[cfg(windows)]
- fn rmdir(p: &Path) -> bool {
- #[fixed_stack_segment]; #[inline(never)];
- unsafe {
- use os::win32::as_utf16_p;
- return do as_utf16_p(p.as_str().unwrap()) |buf| {
- libc::RemoveDirectoryW(buf) != (0 as libc::BOOL)
- };
- }
- }
-
- #[cfg(unix)]
- fn rmdir(p: &Path) -> bool {
- #[fixed_stack_segment]; #[inline(never)];
- do p.with_c_str |buf| {
- unsafe {
- libc::rmdir(buf) == (0 as c_int)
- }
- }
- }
-}
-
/// Changes the current working directory to the specified path, returning
/// whether the change was completed successfully or not.
pub fn change_dir(p: &Path) -> bool {
}
}
-/// Copies a file from one location to another
-pub fn copy_file(from: &Path, to: &Path) -> bool {
- return do_copy_file(from, to);
-
- #[cfg(windows)]
- fn do_copy_file(from: &Path, to: &Path) -> bool {
- #[fixed_stack_segment]; #[inline(never)];
- unsafe {
- use os::win32::as_utf16_p;
- return do as_utf16_p(from.as_str().unwrap()) |fromp| {
- do as_utf16_p(to.as_str().unwrap()) |top| {
- libc::CopyFileW(fromp, top, (0 as libc::BOOL)) !=
- (0 as libc::BOOL)
- }
- }
- }
- }
-
- #[cfg(unix)]
- fn do_copy_file(from: &Path, to: &Path) -> bool {
- #[fixed_stack_segment]; #[inline(never)];
- unsafe {
- let istream = do from.with_c_str |fromp| {
- do "rb".with_c_str |modebuf| {
- libc::fopen(fromp, modebuf)
- }
- };
- if istream as uint == 0u {
- return false;
- }
- // Preserve permissions
- let from_mode = from.get_mode().expect("copy_file: couldn't get permissions \
- for source file");
-
- let ostream = do to.with_c_str |top| {
- do "w+b".with_c_str |modebuf| {
- libc::fopen(top, modebuf)
- }
- };
- if ostream as uint == 0u {
- fclose(istream);
- return false;
- }
- let bufsize = 8192u;
- let mut buf = vec::with_capacity::<u8>(bufsize);
- let mut done = false;
- let mut ok = true;
- while !done {
- do buf.as_mut_buf |b, _sz| {
- let nread = libc::fread(b as *mut c_void, 1u as size_t,
- bufsize as size_t,
- istream);
- if nread > 0 as size_t {
- if libc::fwrite(b as *c_void, 1u as size_t, nread,
- ostream) != nread {
- ok = false;
- done = true;
- }
- } else {
- done = true;
- }
- }
- }
- fclose(istream);
- fclose(ostream);
-
- // Give the new file the old file's permissions
- if do to.with_c_str |to_buf| {
- libc::chmod(to_buf, from_mode as libc::mode_t)
- } != 0 {
- return false; // should be a condition...
- }
- return ok;
- }
- }
-}
-
-/// Deletes an existing file
-pub fn remove_file(p: &Path) -> bool {
- return unlink(p);
-
- #[cfg(windows)]
- fn unlink(p: &Path) -> bool {
- #[fixed_stack_segment]; #[inline(never)];
- unsafe {
- use os::win32::as_utf16_p;
- return do as_utf16_p(p.as_str().unwrap()) |buf| {
- libc::DeleteFileW(buf) != (0 as libc::BOOL)
- };
- }
- }
-
- #[cfg(unix)]
- fn unlink(p: &Path) -> bool {
- #[fixed_stack_segment]; #[inline(never)];
- unsafe {
- do p.with_c_str |buf| {
- libc::unlink(buf) == (0 as c_int)
- }
- }
- }
-}
-
-/// Renames an existing file or directory
-pub fn rename_file(old: &Path, new: &Path) -> bool {
- #[fixed_stack_segment]; #[inline(never)];
- unsafe {
- do old.with_c_str |old_buf| {
- do new.with_c_str |new_buf| {
- libc::rename(old_buf, new_buf) == (0 as c_int)
- }
- }
- }
-}
-
#[cfg(unix)]
/// Returns the platform-specific value of errno
pub fn errno() -> int {
#[cfg(test)]
mod tests {
use c_str::ToCStr;
- use libc::{c_int, c_void, size_t};
- use libc;
use option::Some;
use option;
use os::{env, getcwd, getenv, make_absolute, args};
- use os::{remove_file, setenv, unsetenv};
+ use os::{setenv, unsetenv};
use os;
use path::Path;
use rand::Rng;
use rand;
- use run;
use str::StrSlice;
- use libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR};
#[test]
for s in olduserprofile.iter() { setenv("USERPROFILE", *s) }
}
- #[test]
- fn tmpdir() {
- let p = os::tmpdir();
- let s = p.as_str();
- assert!(s.is_some() && s.unwrap() != ".");
- }
-
- // Issue #712
- #[test]
- fn test_list_dir_no_invalid_memory_access() {
- os::list_dir(&Path::new("."));
- }
-
- #[test]
- fn list_dir() {
- let dirs = os::list_dir(&Path::new("."));
- // Just assuming that we've got some contents in the current directory
- assert!(dirs.len() > 0u);
-
- for dir in dirs.iter() {
- debug!("{:?}", (*dir).clone());
- }
- }
-
- #[test]
- #[cfg(not(windows))]
- fn list_dir_root() {
- let dirs = os::list_dir(&Path::new("/"));
- assert!(dirs.len() > 1);
- }
- #[test]
- #[cfg(windows)]
- fn list_dir_root() {
- let dirs = os::list_dir(&Path::new("C:\\"));
- assert!(dirs.len() > 1);
- }
-
-
- #[test]
- fn path_is_dir() {
- use rt::io::file::open;
- use rt::io::{OpenOrCreate, Read};
-
- assert!((os::path_is_dir(&Path::new("."))));
- assert!((!os::path_is_dir(&Path::new("test/stdtest/fs.rs"))));
-
- let mut dirpath = os::tmpdir();
- dirpath.push(format!("rust-test-{}/test-\uac00\u4e00\u30fc\u4f60\u597d",
- rand::random::<u32>())); // 가一ー你好
- debug!("path_is_dir dirpath: {}", dirpath.display());
-
- let mkdir_result = os::mkdir_recursive(&dirpath, (S_IRUSR | S_IWUSR | S_IXUSR) as i32);
- debug!("path_is_dir mkdir_result: {}", mkdir_result);
-
- assert!((os::path_is_dir(&dirpath)));
-
- let mut filepath = dirpath;
- filepath.push("unicode-file-\uac00\u4e00\u30fc\u4f60\u597d.rs");
- debug!("path_is_dir filepath: {}", filepath.display());
-
- open(&filepath, OpenOrCreate, Read); // ignore return; touch only
- assert!((!os::path_is_dir(&filepath)));
-
- assert!((!os::path_is_dir(&Path::new(
- "test/unicode-bogus-dir-\uac00\u4e00\u30fc\u4f60\u597d"))));
- }
-
- #[test]
- fn path_exists() {
- assert!((os::path_exists(&Path::new("."))));
- assert!((!os::path_exists(&Path::new(
- "test/nonexistent-bogus-path"))));
-
- let mut dirpath = os::tmpdir();
- dirpath.push(format!("rust-test-{}/test-\uac01\u4e01\u30fc\u518d\u89c1",
- rand::random::<u32>())); // 각丁ー再见
-
- os::mkdir_recursive(&dirpath, (S_IRUSR | S_IWUSR | S_IXUSR) as i32);
- assert!((os::path_exists(&dirpath)));
- assert!((!os::path_exists(&Path::new(
- "test/unicode-bogus-path-\uac01\u4e01\u30fc\u518d\u89c1"))));
- }
-
- #[test]
- fn copy_file_does_not_exist() {
- assert!(!os::copy_file(&Path::new("test/nonexistent-bogus-path"),
- &Path::new("test/other-bogus-path")));
- assert!(!os::path_exists(&Path::new("test/other-bogus-path")));
- }
-
- #[test]
- fn copy_file_ok() {
- #[fixed_stack_segment]; #[inline(never)];
-
- unsafe {
- let tempdir = getcwd(); // would like to use $TMPDIR,
- // doesn't seem to work on Linux
- let input = tempdir.join("in.txt");
- let out = tempdir.join("out.txt");
-
- /* Write the temp input file */
- let ostream = do input.with_c_str |fromp| {
- do "w+b".with_c_str |modebuf| {
- libc::fopen(fromp, modebuf)
- }
- };
- assert!((ostream as uint != 0u));
- let s = ~"hello";
- do "hello".with_c_str |buf| {
- let write_len = libc::fwrite(buf as *c_void,
- 1u as size_t,
- (s.len() + 1u) as size_t,
- ostream);
- assert_eq!(write_len, (s.len() + 1) as size_t)
- }
- assert_eq!(libc::fclose(ostream), (0u as c_int));
- let in_mode = input.get_mode();
- let rs = os::copy_file(&input, &out);
- if (!os::path_exists(&input)) {
- fail!("{} doesn't exist", input.display());
- }
- assert!((rs));
- // FIXME (#9639): This needs to handle non-utf8 paths
- let rslt = run::process_status("diff", [input.as_str().unwrap().to_owned(),
- out.as_str().unwrap().to_owned()]);
- assert_eq!(rslt, 0);
- assert_eq!(out.get_mode(), in_mode);
- assert!((remove_file(&input)));
- assert!((remove_file(&out)));
- }
- }
-
- #[test]
- fn recursive_mkdir_slash() {
- let path = Path::new("/");
- assert!(os::mkdir_recursive(&path, (S_IRUSR | S_IWUSR | S_IXUSR) as i32));
- }
-
#[test]
fn memory_map_rw() {
use result::{Ok, Err};
use result::{Ok, Err};
use os::*;
use libc::*;
+ use rt::io::file;
#[cfg(unix)]
#[fixed_stack_segment]
let mut path = tmpdir();
path.push("mmap_file.tmp");
let size = MemoryMap::granularity() * 2;
- remove_file(&path);
let fd = unsafe {
let fd = do path.with_c_str |path| {
assert!(*chunk.data == 0xbe);
close(fd);
}
+ file::unlink(&path);
}
// More recursive_mkdir tests are in extra::tempfile
use vec::{CopyableVector, RSplitIterator, SplitIterator, Vector, VectorVector};
use super::{BytesContainer, GenericPath, GenericPathUnsafe};
-#[cfg(not(target_os = "win32"))]
-use rt::io::{FileStat, file, io_error};
-
/// Iterator that yields successive components of a Path as &[u8]
pub type ComponentIter<'self> = SplitIterator<'self, u8>;
/// Iterator that yields components of a Path in reverse as &[u8]
static dot_static: &'static [u8] = bytes!(".");
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 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
- pub fn exists(&self) -> bool {
- match self.stat() {
- None => false,
- Some(_) => true
- }
- }
-
- /// Returns the filesize of the represented file
- pub fn get_size(&self) -> Option<u64> {
- match self.stat() {
- None => None,
- Some(st) => Some(st.size)
- }
- }
-
- /// Returns the mode of the represented file
- pub fn get_mode(&self) -> Option<uint> {
- match self.stat() {
- None => None,
- Some(st) => Some(st.mode as uint)
- }
- }
-}
-
-#[cfg(target_os = "freebsd")]
-#[cfg(target_os = "linux")]
-#[cfg(target_os = "macos")]
-impl Path {
- /// 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.accessed)
- }
- }
-
- /// 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.modified)
- }
- }
-
- /// 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.created)
- }
- }
-}
-
#[cfg(test)]
mod tests {
use super::*;
use rand::Rng;
use ops::Drop;
+use path::Path;
#[cfg(unix)]
use rand::reader::ReaderRng;
#[cfg(unix)]
-use rt::io::{file, Open, Read};
+use rt::io::file;
#[cfg(windows)]
use cast;
/// This does not block.
#[cfg(unix)]
pub struct OSRng {
- priv inner: ReaderRng<file::FileStream>
+ priv inner: ReaderRng<file::FileReader>
}
/// A random number generator that retrieves randomness straight from
/// the operating system. Platform sources:
/// Create a new `OSRng`.
#[cfg(unix)]
pub fn new() -> OSRng {
- let reader = file::open(& &"/dev/urandom", Open, Read).expect("Error opening /dev/urandom");
+ let reader = file::open(&Path::new("/dev/urandom"));
+ let reader = reader.expect("Error opening /dev/urandom");
let reader_rng = ReaderRng::new(reader);
OSRng { inner: reader_rng }
This module provides a set of functions and traits for working
with regular files & directories on a filesystem.
-At the top-level of the module are a set of freestanding functions,
-associated with various filesystem operations. They all operate
-on a `ToCStr` object. This trait is already defined for common
-objects such as strings and `Path` instances.
+At the top-level of the module are a set of freestanding functions, associated
+with various filesystem operations. They all operate on a `Path` object.
All operations in this module, including those as part of `FileStream` et al
block the task during execution. Most will raise `std::rt::io::io_error`
conditions in the event of failure.
-Also included in this module are the `FileInfo` and `DirectoryInfo` traits. When
-`use`'d alongside a value whose type implements them (A `std::path::Path` impl is
-a part of this module), they expose a set of functions for operations against
-a given file location, depending on whether the path already exists. Whenever
-possible, the `{FileInfo, DirectoryInfo}` preserve the same semantics as their
-free function counterparts.
+Also included in this module is an implementation block on the `Path` object
+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.
+
*/
-use prelude::*;
use c_str::ToCStr;
use super::{Reader, Writer, Seek};
-use super::{SeekStyle, Read, Write};
+use super::{SeekStyle, Read, Write, Open, CreateOrTruncate,
+ FileMode, FileAccess, FileStat, io_error, FilePermission};
use rt::rtio::{RtioFileStream, IoFactory, with_local_io};
-use rt::io::{io_error, EndOfFile,
- FileMode, FileAccess, FileStat, IoError,
- PathAlreadyExists, PathDoesntExist,
- MismatchedFileTypeForOperation, ignore_io_error};
-use option::{Some, None};
-use path::Path;
+use rt::io;
+use option::{Some, None, Option};
+use result::{Ok, Err};
+use path;
+use path::{Path, GenericPath};
/// Open a file for reading/writing, as indicated by `path`.
///
/// # Example
///
-/// use std;
-/// use std::path::Path;
-/// use std::rt::io::file::open;
-/// use std::rt::io::{FileMode, FileAccess};
+/// use std::rt::{io, file, io_error};
///
-/// let p = &Path("/some/file/path.txt");
+/// let p = Path::new("/some/file/path.txt");
///
/// do io_error::cond.trap(|_| {
/// // hoo-boy...
/// }).inside {
-/// let stream = match open(p, Create, ReadWrite) {
+/// let stream = match file::open_stream(&p, io::Create, io::ReadWrite) {
/// Some(s) => s,
/// None => fail!("whoops! I'm sure this raised, anyways..")
/// };
///
/// Note that, with this function, a `FileStream` is returned regardless of
/// the access-limitations indicated by `FileAccess` (e.g. calling `write` on a
-/// `FileStream` opened as `ReadOnly` will raise an `io_error` condition at runtime). If you
-/// desire a more-correctly-constrained interface to files, use the
-/// `{open_stream, open_reader, open_writer}` methods that are a part of `FileInfo`
+/// `FileStream` opened as `ReadOnly` will raise an `io_error` condition at
+/// runtime). If you desire a more-correctly-constrained interface to files,
+/// use the `{open_stream, open, create}` methods that are a part of `Path`.
///
/// # Errors
///
-/// This function will raise an `io_error` condition under a number of different circumstances,
-/// to include but not limited to:
+/// This function will raise an `io_error` condition under a number of different
+/// circumstances, to include but not limited to:
///
-/// * Opening a file that already exists with `FileMode` of `Create` or vice versa (e.g.
-/// opening a non-existant file with `FileMode` or `Open`)
-/// * Attempting to open a file with a `FileAccess` that the user lacks permissions
-/// for
+/// * Opening a file that already exists with `FileMode` of `Create` or vice
+/// versa (e.g. opening a non-existant file with `FileMode` or `Open`)
+/// * Attempting to open a file with a `FileAccess` that the user lacks
+/// permissions for
/// * Filesystem-level errors (full disk, etc)
-pub fn open<P: ToCStr>(path: &P,
- mode: FileMode,
- access: FileAccess
- ) -> Option<FileStream> {
+pub fn open_stream(path: &Path,
+ mode: FileMode,
+ access: FileAccess) -> Option<FileStream> {
do with_local_io |io| {
match io.fs_open(&path.to_c_str(), mode, access) {
Ok(fd) => Some(FileStream {
}
}
+/// Attempts to open a file in read-only mode. This function is equivalent to
+/// `open_stream(path, Open, Read)`, and will raise all of the same errors that
+/// `open_stream` does.
+///
+/// For more information, see the `open_stream` function.
+pub fn open(path: &Path) -> Option<FileReader> {
+ open_stream(path, Open, Read).map(|s| FileReader { stream: s })
+}
+
+/// Attempts to create a file in write-only mode. This function is equivalent to
+/// `open_stream(path, CreateOrTruncate, Write)`, and will raise all of the
+/// same errors that `open_stream` does.
+///
+/// For more information, see the `open_stream` function.
+pub fn create(path: &Path) -> Option<FileWriter> {
+ open_stream(path, CreateOrTruncate, Write).map(|s| FileWriter { stream: s })
+}
+
/// Unlink a file from the underlying filesystem.
///
/// # Example
///
-/// use std;
-/// use std::path::Path;
-/// use std::rt::io::file::unlink;
+/// use std::rt::io::file;
///
-/// let p = &Path("/some/file/path.txt");
-/// unlink(p);
+/// let p = Path::new("/some/file/path.txt");
+/// file::unlink(&p);
/// // if we made it here without failing, then the
/// // unlink operation was successful
///
///
/// # Errors
///
-/// This function will raise an `io_error` condition if the user lacks permissions to
-/// remove the file or if some other filesystem-level error occurs
-pub fn unlink<P: ToCStr>(path: &P) {
+/// 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 with_local_io |io| {
match io.fs_unlink(&path.to_c_str()) {
- Ok(_) => Some(()),
+ Ok(()) => Some(()),
Err(ioerr) => {
io_error::cond.raise(ioerr);
None
///
/// # Example
///
-/// use std;
-/// use std::path::Path;
-/// use std::rt::io::file::mkdir;
+/// use std::libc::S_IRWXU;
+/// use std::rt::io::file;
///
-/// let p = &Path("/some/dir");
-/// mkdir(p);
+/// let p = Path::new("/some/dir");
+/// file::mkdir(&p, S_IRWXU as int);
/// // If we got here, our directory exists! Horray!
///
/// # Errors
///
-/// This call will raise an `io_error` condition if the user lacks permissions to make a
-/// new directory at the provided path, or if the directory already exists
-pub fn mkdir<P: ToCStr>(path: &P) {
+/// This call will raise an `io_error` condition if the user lacks permissions
+/// to make a new directory at the provided path, or if the directory already
+/// exists.
+pub fn mkdir(path: &Path, mode: FilePermission) {
do with_local_io |io| {
- match io.fs_mkdir(&path.to_c_str()) {
+ match io.fs_mkdir(&path.to_c_str(), mode) {
Ok(_) => Some(()),
Err(ioerr) => {
io_error::cond.raise(ioerr);
///
/// # Example
///
-/// use std;
-/// use std::path::Path;
-/// use std::rt::io::file::rmdir;
+/// use std::rt::io::file;
///
-/// let p = &Path("/some/dir");
-/// rmdir(p);
+/// let p = Path::new("/some/dir");
+/// file::rmdir(&p);
/// // good riddance, you mean ol' directory
///
/// # Errors
///
-/// This call will raise an `io_error` condition if the user lacks permissions to remove the
-/// directory at the provided path, or if the directory isn't empty
-pub fn rmdir<P: ToCStr>(path: &P) {
+/// This call will raise an `io_error` condition if the user lacks permissions
+/// to remove the directory at the provided path, or if the directory isn't
+/// empty.
+pub fn rmdir(path: &Path) {
do with_local_io |io| {
match io.fs_rmdir(&path.to_c_str()) {
Ok(_) => Some(()),
/// Given a path, query the file system to get information about a file,
/// directory, etc.
///
-/// Returns a `Some(std::rt::io::PathInfo)` on success
+/// 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;
-/// use std::path::Path;
-/// use std::rt::io::file::stat;
+/// use std::rt::io::{file, io_error};
///
-/// let p = &Path("/some/file/path.txt");
+/// let p = Path::new("/some/file/path.txt");
///
/// do io_error::cond.trap(|_| {
/// // hoo-boy...
/// }).inside {
-/// let info = match stat(p) {
-/// Some(s) => s,
-/// None => fail!("whoops! I'm sure this raised, anyways..");
-/// }
-/// if stat.is_file {
+/// let info = file::stat(p);
+/// if info.is_file {
/// // just imagine the possibilities ...
/// }
-///
-/// // the file stream will be closed at the end of this block
/// }
-/// // ..
///
/// # 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<P: ToCStr>(path: &P) -> Option<FileStat> {
+pub fn stat(path: &Path) -> FileStat {
do with_local_io |io| {
match io.fs_stat(&path.to_c_str()) {
Ok(p) => Some(p),
None
}
}
- }
+ }.unwrap_or_else(|| {
+ FileStat {
+ path: Path::new(path.to_c_str()),
+ is_file: false,
+ is_dir: false,
+ device: 0,
+ mode: 0,
+ inode: 0,
+ size: 0,
+ created: 0,
+ modified: 0,
+ accessed: 0,
+ }
+ })
}
/// Retrieve a vector containing all entries within a provided directory
///
/// # Example
///
-/// use std;
-/// use std::path::Path;
-/// use std::rt::io::file::readdir;
+/// use std::rt::io::file;
///
/// fn visit_dirs(dir: &Path, cb: &fn(&Path)) {
/// if dir.is_dir() {
-/// let contents = dir.readdir();
+/// let contents = file::readdir(dir).unwrap();
/// for entry in contents.iter() {
/// if entry.is_dir() { visit_dirs(entry, cb); }
/// else { cb(entry); }
///
/// # Errors
///
-/// Will raise an `io_error` condition if the provided `path` doesn't exist,
+/// Will raise an `io_error` condition if the provided `from` doesn't exist,
/// the process lacks permissions to view the contents or if the `path` points
/// at a non-directory file
-pub fn readdir<P: ToCStr>(path: &P) -> Option<~[Path]> {
+pub fn readdir(path: &Path) -> ~[Path] {
do with_local_io |io| {
match io.fs_readdir(&path.to_c_str(), 0) {
Ok(p) => Some(p),
None
}
}
- }
+ }.unwrap_or_else(|| ~[])
}
-/// Constrained version of `FileStream` that only exposes read-specific operations.
+/// Rename a file or directory to a new name.
///
-/// Can be retreived via `FileInfo.open_reader()`.
-pub struct FileReader { priv stream: FileStream }
+/// # 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 with_local_io |io| {
+ match io.fs_rename(&from.to_c_str(), &to.to_c_str()) {
+ Ok(()) => Some(()),
+ Err(ioerr) => {
+ io_error::cond.raise(ioerr);
+ None
+ }
+ }
+ };
+}
-/// a `std::rt::io::Reader` trait impl for file I/O.
-impl Reader for FileReader {
- fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
- self.stream.read(buf)
+/// Copies the contents of one file to another.
+///
+/// # 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 if the provided `from` doesn't exist,
+/// the process lacks permissions to view the contents, or if some other
+/// intermittent I/O error occurs (such as `to` couldn't be created).
+pub fn copy(from: &Path, to: &Path) {
+ let mut reader = match open(from) { Some(f) => f, None => return };
+ let mut writer = match 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
+ }
}
- fn eof(&mut self) -> bool {
- self.stream.eof()
- }
+ // FIXME(#10131) this is an awful way to pull out the permission bits.
+ // If this comment is removed, then there should be a test
+ // asserting that permission bits are maintained using the
+ // permission interface created.
+ chmod(to, (from.stat().mode & 0xfff) as u32);
}
-/// a `std::rt::io::Seek` trait impl for file I/O.
-impl Seek for FileReader {
- fn tell(&self) -> u64 {
- self.stream.tell()
- }
+// This function is not public because it's got a terrible interface for `mode`
+// FIXME(#10131)
+fn chmod(path: &Path, mode: u32) {
+ do with_local_io |io| {
+ match io.fs_chmod(&path.to_c_str(), mode) {
+ Ok(()) => Some(()),
+ Err(ioerr) => {
+ io_error::cond.raise(ioerr);
+ None
+ }
+ }
+ };
+}
- fn seek(&mut self, pos: i64, style: SeekStyle) {
- self.stream.seek(pos, style);
+/// Recursively walk a directory structure. This function will call the
+/// provided closure on all directories and files found inside the path
+/// pointed to by `self`. If the closure returns `false`, then the iteration
+/// will be short-circuited.
+pub fn walk_dir(path: &Path, f: &fn(&Path) -> bool) -> bool {
+ let files = readdir(path);
+ files.iter().advance(|q| {
+ f(q) && (!q.is_dir() || walk_dir(q, |p| f(p)))
+ })
+}
+
+/// Recursively create a directory and all of its parent components if they
+/// are missing.
+///
+/// # Failure
+///
+/// This function will raise on the `io_error` condition if an error
+/// happens, see `file::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,
+ // should we return false?
+ if path.is_dir() {
+ return
+ }
+ if path.filename().is_some() {
+ mkdir_recursive(&path.dir_path(), mode);
}
+ mkdir(path, mode)
}
-/// Constrained version of `FileStream` that only exposes write-specific operations.
+/// Removes a directory at this path, after removing all its contents. Use
+/// carefully!
///
-/// Can be retreived via `FileInfo.open_writer()`.
+/// # Failure
+///
+/// This function will raise on the `io_error` condition if an error
+/// happens. See `file::unlink` and `file::readdir` for possible error
+/// conditions.
+pub fn rmdir_recursive(path: &Path) {
+ do walk_dir(path) |inner| {
+ if inner.is_dir() {
+ rmdir_recursive(inner);
+ } else {
+ unlink(inner);
+ }
+ true
+ };
+ // Directory should now be empty
+ rmdir(path);
+}
+
+/// Constrained version of `FileStream` that only exposes read-specific
+/// operations.
+///
+/// Can be retreived via `Path.open()` or `file::open`.
+pub struct FileReader { priv stream: FileStream }
+
+impl Reader for FileReader {
+ fn read(&mut self, buf: &mut [u8]) -> Option<uint> { self.stream.read(buf) }
+ fn eof(&mut self) -> bool { self.stream.eof() }
+}
+
+impl Seek for FileReader {
+ fn tell(&self) -> u64 { self.stream.tell() }
+ fn seek(&mut self, p: i64, s: SeekStyle) { self.stream.seek(p, s) }
+}
+
+/// Constrained version of `FileStream` that only exposes write-specific
+/// operations.
+///
+/// Can be retreived via `Path.create()` or `file::create`.
pub struct FileWriter { priv stream: FileStream }
-/// a `std::rt::io::Writer` trait impl for file I/O.
impl Writer for FileWriter {
- fn write(&mut self, buf: &[u8]) {
- self.stream.write(buf);
- }
-
- fn flush(&mut self) {
- self.stream.flush();
- }
+ fn write(&mut self, buf: &[u8]) { self.stream.write(buf); }
+ fn flush(&mut self) { self.stream.flush(); }
}
-/// a `std::rt::io::Seek` trait impl for file I/O.
impl Seek for FileWriter {
- fn tell(&self) -> u64 {
- self.stream.tell()
- }
-
- fn seek(&mut self, pos: i64, style: SeekStyle) {
- self.stream.seek(pos, style);
- }
+ fn tell(&self) -> u64 { self.stream.tell() }
+ fn seek(&mut self, p: i64, s: SeekStyle) { self.stream.seek(p, s); }
}
/// Unconstrained file access type that exposes read and write operations
///
-/// Can be retreived via `file::open()` and `FileInfo.open_stream()`.
+/// Can be retreived via `file::open()` and `Path.open_stream()`.
///
/// # Errors
///
/// time, via the `FileAccess` parameter to `file::open()`.
///
/// For this reason, it is best to use the access-constrained wrappers that are
-/// exposed via `FileInfo.open_reader()` and `FileInfo.open_writer()`.
+/// exposed via `Path.open()` and `Path.create()`.
pub struct FileStream {
priv fd: ~RtioFileStream,
priv last_nread: int,
}
-/// a `std::rt::io::Reader` trait impl for file I/O.
impl Reader for FileStream {
fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
match self.fd.read(buf) {
},
Err(ioerr) => {
// EOF is indicated by returning None
- if ioerr.kind != EndOfFile {
+ if ioerr.kind != io::EndOfFile {
io_error::cond.raise(ioerr);
}
return None;
}
}
- fn eof(&mut self) -> bool {
- self.last_nread == 0
- }
+ fn eof(&mut self) -> bool { self.last_nread == 0 }
}
-/// a `std::rt::io::Writer` trait impl for file I/O.
impl Writer for FileStream {
fn write(&mut self, buf: &[u8]) {
match self.fd.write(buf) {
}
}
-/// a `std::rt::io:Seek` trait impl for file I/O.
impl Seek for FileStream {
fn tell(&self) -> u64 {
let res = self.fd.tell();
}
}
-/// Shared functionality between `FileInfo` and `DirectoryInfo`
-pub trait FileSystemInfo {
- /// Get the filesystem path that this instance points at,
- /// whether it is valid or not. In this way, it can be used to
- /// to specify a path of a non-existent file which it
- /// later creates
- fn get_path<'a>(&'a self) -> &'a Path;
-
- /// Get information on the file, directory, etc at the provided path
+impl path::Path {
+ /// Get information on the file, directory, etc at this path.
///
/// Consult the `file::stat` documentation for more info.
///
- /// This call preserves identical runtime/error semantics with `file::stat`
- fn stat(&self) -> Option<FileStat> {
- stat(self.get_path())
- }
+ /// This call preserves identical runtime/error semantics with `file::stat`.
+ pub fn stat(&self) -> FileStat { stat(self) }
- /// Boolean value indicator whether the underlying file exists on the filesystem
+ /// Boolean value indicator whether the underlying file exists on the local
+ /// filesystem. This will return true if the path points to either a
+ /// directory or a file.
///
/// # Errors
///
/// Will not raise a condition
- fn exists(&self) -> bool {
- match ignore_io_error(|| self.stat()) {
- Some(_) => true,
- None => false
- }
+ pub fn exists(&self) -> bool {
+ io::result(|| self.stat()).is_ok()
}
-}
-
-/// Represents a file, whose underlying path may or may not be valid
-///
-/// # Example
-///
-/// * Check if a file exists, reading from it if so
-///
-/// ```rust
-/// use std;
-/// use std::path::Path;
-/// use std::rt::io::file::{FileInfo, FileReader};
-///
-/// let f = &Path("/some/file/path.txt");
-/// if f.exists() {
-/// let reader = f.open_reader(Open);
-/// let mut mem = [0u8, 8*64000];
-/// reader.read(mem);
-/// // ...
-/// }
-/// ```
-///
-/// * Is the given path a file?
-///
-/// ```rust
-/// let f = get_file_path_from_wherever();
-/// match f.is_file() {
-/// true => doing_something_with_a_file(f),
-/// _ => {}
-/// }
-/// ```
-pub trait FileInfo : FileSystemInfo {
- /// Whether the underlying implemention (be it a file path,
- /// or something else) points at a "regular file" on the FS. Will return
- /// false for paths to non-existent locations or directories or
- /// other non-regular files (named pipes, etc).
+ /// Whether the underlying implemention (be it a file path, or something
+ /// else) points at a "regular file" on the FS. Will return false for paths
+ /// to non-existent locations or directories or other non-regular files
+ /// (named pipes, etc).
///
/// # Errors
///
/// Will not raise a condition
- fn is_file(&self) -> bool {
- match ignore_io_error(|| self.stat()) {
- Some(s) => s.is_file,
- None => false
- }
- }
-
- /// Attempts to open a regular file for reading/writing based
- /// on provided inputs
- ///
- /// See `file::open` for more information on runtime semantics and error conditions
- fn open_stream(&self, mode: FileMode, access: FileAccess) -> Option<FileStream> {
- match ignore_io_error(|| self.stat()) {
- Some(s) => match s.is_file {
- true => open(self.get_path(), mode, access),
- false => None
- },
- None => open(self.get_path(), mode, access)
+ pub fn is_file(&self) -> bool {
+ match io::result(|| self.stat()) {
+ Ok(s) => s.is_file,
+ Err(*) => false
}
}
- /// Attempts to open a regular file in read-only mode, based
- /// on provided inputs
- ///
- /// See `file::open` for more information on runtime semantics and error conditions
- fn open_reader(&self, mode: FileMode) -> Option<FileReader> {
- match self.open_stream(mode, Read) {
- Some(s) => Some(FileReader { stream: s}),
- None => None
- }
- }
-
- /// Attempts to open a regular file in write-only mode, based
- /// on provided inputs
- ///
- /// See `file::open` for more information on runtime semantics and error conditions
- fn open_writer(&self, mode: FileMode) -> Option<FileWriter> {
- match self.open_stream(mode, Write) {
- Some(s) => Some(FileWriter { stream: s}),
- None => None
- }
- }
-
- /// Attempt to remove a file from the filesystem
- ///
- /// See `file::unlink` for more information on runtime semantics and error conditions
- fn unlink(&self) {
- unlink(self.get_path());
- }
-}
-
-/// `FileSystemInfo` implementation for `Path`s
-impl FileSystemInfo for Path {
- fn get_path<'a>(&'a self) -> &'a Path { self }
-}
-
-/// `FileInfo` implementation for `Path`s
-impl FileInfo for Path { }
-
-/// Represents a directory, whose underlying path may or may not be valid
-///
-/// # Example
-///
-/// * Check if a directory exists, `mkdir`'ing it if not
-///
-/// ```rust
-/// use std;
-/// use std::path::Path;
-/// use std::rt::io::file::{DirectoryInfo};
-///
-/// let dir = &Path("/some/dir");
-/// if !dir.exists() {
-/// dir.mkdir();
-/// }
-/// ```
-///
-/// * Is the given path a directory? If so, iterate on its contents
-///
-/// ```rust
-/// fn visit_dirs(dir: &Path, cb: &fn(&Path)) {
-/// if dir.is_dir() {
-/// let contents = dir.readdir();
-/// for entry in contents.iter() {
-/// if entry.is_dir() { visit_dirs(entry, cb); }
-/// else { cb(entry); }
-/// }
-/// }
-/// else { fail!("nope"); }
-/// }
-/// ```
-pub trait DirectoryInfo : FileSystemInfo {
/// Whether the underlying implemention (be it a file path,
/// or something else) is pointing at a directory in the underlying FS.
/// Will return false for paths to non-existent locations or if the item is
/// # Errors
///
/// Will not raise a condition
- fn is_dir(&self) -> bool {
- match ignore_io_error(|| self.stat()) {
- Some(s) => s.is_dir,
- None => false
+ pub fn is_dir(&self) -> bool {
+ match io::result(|| self.stat()) {
+ Ok(s) => s.is_dir,
+ Err(*) => false
}
}
-
- /// Create a directory at the location pointed to by the
- /// type underlying the given `DirectoryInfo`.
- ///
- /// # Errors
- ///
- /// This method will raise a `PathAlreadyExists` kind of `io_error` condition
- /// if the provided path exists
- ///
- /// See `file::mkdir` for more information on runtime semantics and error conditions
- fn mkdir(&self) {
- match ignore_io_error(|| self.stat()) {
- Some(_) => {
- let path = self.get_path();
- io_error::cond.raise(IoError {
- kind: PathAlreadyExists,
- desc: "Path already exists",
- detail:
- Some(format!("{} already exists; can't mkdir it",
- path.display()))
- })
- },
- None => mkdir(self.get_path())
- }
- }
-
- /// Remove a directory at the given location.
- ///
- /// # Errors
- ///
- /// This method will raise a `PathDoesntExist` kind of `io_error` condition
- /// if the provided path exists. It will raise a `MismatchedFileTypeForOperation`
- /// kind of `io_error` condition if the provided path points at any
- /// non-directory file type
- ///
- /// See `file::rmdir` for more information on runtime semantics and error conditions
- fn rmdir(&self) {
- match ignore_io_error(|| self.stat()) {
- Some(s) => {
- match s.is_dir {
- true => rmdir(self.get_path()),
- false => {
- let path = self.get_path();
- let ioerr = IoError {
- kind: MismatchedFileTypeForOperation,
- desc: "Cannot do rmdir() on a non-directory",
- detail: Some(format!(
- "{} is a non-directory; can't rmdir it",
- path.display()))
- };
- io_error::cond.raise(ioerr);
- }
- }
- },
- None => {
- let path = self.get_path();
- io_error::cond.raise(IoError {
- kind: PathDoesntExist,
- desc: "Path doesn't exist",
- detail: Some(format!("{} doesn't exist; can't rmdir it",
- path.display()))
- })
- }
- }
- }
-
- // Get a collection of all entries at the given
- // directory
- fn readdir(&self) -> Option<~[Path]> {
- readdir(self.get_path())
- }
}
-/// `DirectoryInfo` impl for `path::Path`
-impl DirectoryInfo for Path { }
-
#[cfg(test)]
mod test {
- use super::super::{SeekSet, SeekCur, SeekEnd,
- io_error, Read, Create, Open, ReadWrite};
- use super::super::super::test::*;
+ use path::{Path, GenericPath};
+ use result::{Ok, Err};
use option::{Some, None};
- use path::Path;
- use super::*;
use iter::range;
+ use rt::test::run_in_mt_newsched_task;
+ use super::{open_stream, unlink, stat, copy, rmdir, mkdir, readdir,
+ open, create, rmdir_recursive, mkdir_recursive};
+
+ use rt::io;
+ use rt::io::Reader;
+ use super::super::{SeekSet, SeekCur, SeekEnd,
+ io_error, Read, Create, Open, ReadWrite};
+ use vec::Vector;
+
+ fn tmpdir() -> Path {
+ use os;
+ use rand;
+ let ret = os::tmpdir().join(format!("rust-{}", rand::random::<u32>()));
+ mkdir(&ret, io::UserRWX);
+ ret
+ }
+
#[test]
fn file_test_io_smoke_test() {
do run_in_mt_newsched_task {
let message = "it's alright. have a good time";
let filename = &Path::new("./tmp/file_rt_io_file_test.txt");
{
- let mut write_stream = open(filename, Create, ReadWrite).unwrap();
+ let mut write_stream = open_stream(filename, Create, ReadWrite);
write_stream.write(message.as_bytes());
}
{
use str;
- let mut read_stream = open(filename, Open, Read).unwrap();
+ let mut read_stream = open_stream(filename, Open, Read);
let mut read_buf = [0, .. 1028];
let read_str = match read_stream.read(read_buf).unwrap() {
-1|0 => fail!("shouldn't happen"),
do io_error::cond.trap(|_| {
called = true;
}).inside {
- let result = open(filename, Open, Read);
+ let result = open_stream(filename, Open, Read);
assert!(result.is_none());
}
assert!(called);
let mut read_mem = [0, .. 8];
let filename = &Path::new("./tmp/file_rt_io_file_test_positional.txt");
{
- let mut rw_stream = open(filename, Create, ReadWrite).unwrap();
+ let mut rw_stream = open_stream(filename, Create, ReadWrite);
rw_stream.write(message.as_bytes());
}
{
- let mut read_stream = open(filename, Open, Read).unwrap();
+ let mut read_stream = open_stream(filename, Open, Read);
{
let read_buf = read_mem.mut_slice(0, 4);
read_stream.read(read_buf);
let mut tell_pos_post_read;
let filename = &Path::new("./tmp/file_rt_io_file_test_seeking.txt");
{
- let mut rw_stream = open(filename, Create, ReadWrite).unwrap();
+ let mut rw_stream = open_stream(filename, Create, ReadWrite);
rw_stream.write(message.as_bytes());
}
{
- let mut read_stream = open(filename, Open, Read).unwrap();
+ let mut read_stream = open_stream(filename, Open, Read);
read_stream.seek(set_cursor as i64, SeekSet);
tell_pos_pre_read = read_stream.tell();
read_stream.read(read_mem);
let mut read_mem = [0, .. 13];
let filename = &Path::new("./tmp/file_rt_io_file_test_seek_and_write.txt");
{
- let mut rw_stream = open(filename, Create, ReadWrite).unwrap();
+ let mut rw_stream = open_stream(filename, Create, ReadWrite);
rw_stream.write(initial_msg.as_bytes());
rw_stream.seek(seek_idx as i64, SeekSet);
rw_stream.write(overwrite_msg.as_bytes());
}
{
- let mut read_stream = open(filename, Open, Read).unwrap();
+ let mut read_stream = open_stream(filename, Open, Read);
read_stream.read(read_mem);
}
unlink(filename);
let mut read_mem = [0, .. 4];
let filename = &Path::new("./tmp/file_rt_io_file_test_seek_shakedown.txt");
{
- let mut rw_stream = open(filename, Create, ReadWrite).unwrap();
+ let mut rw_stream = open_stream(filename, Create, ReadWrite);
rw_stream.write(initial_msg.as_bytes());
}
{
- let mut read_stream = open(filename, Open, Read).unwrap();
+ let mut read_stream = open_stream(filename, Open, Read);
read_stream.seek(-4, SeekEnd);
read_stream.read(read_mem);
do run_in_mt_newsched_task {
let filename = &Path::new("./tmp/file_stat_correct_on_is_file.txt");
{
- let mut fs = open(filename, Create, ReadWrite).unwrap();
+ let mut fs = open_stream(filename, Create, ReadWrite);
let msg = "hw";
fs.write(msg.as_bytes());
}
- let stat_res = match stat(filename) {
- Some(s) => s,
- None => fail!("shouldn't happen")
- };
+ let stat_res = stat(filename);
assert!(stat_res.is_file);
unlink(filename);
}
fn file_test_stat_is_correct_on_is_dir() {
do run_in_mt_newsched_task {
let filename = &Path::new("./tmp/file_stat_correct_on_is_dir");
- mkdir(filename);
- let stat_res = match stat(filename) {
- Some(s) => s,
- None => fail!("shouldn't happen")
- };
+ mkdir(filename, io::UserRWX);
+ let stat_res = filename.stat();
assert!(stat_res.is_dir);
rmdir(filename);
}
fn file_test_fileinfo_false_when_checking_is_file_on_a_directory() {
do run_in_mt_newsched_task {
let dir = &Path::new("./tmp/fileinfo_false_on_dir");
- mkdir(dir);
+ mkdir(dir, io::UserRWX);
assert!(dir.is_file() == false);
rmdir(dir);
}
fn file_test_fileinfo_check_exists_before_and_after_file_creation() {
do run_in_mt_newsched_task {
let file = &Path::new("./tmp/fileinfo_check_exists_b_and_a.txt");
- {
- let msg = "foo".as_bytes();
- let mut w = file.open_writer(Create);
- w.write(msg);
- }
+ create(file).write(bytes!("foo"));
assert!(file.exists());
- file.unlink();
+ unlink(file);
assert!(!file.exists());
}
}
do run_in_mt_newsched_task {
let dir = &Path::new("./tmp/before_and_after_dir");
assert!(!dir.exists());
- dir.mkdir();
+ mkdir(dir, io::UserRWX);
assert!(dir.exists());
assert!(dir.is_dir());
- dir.rmdir();
+ rmdir(dir);
assert!(!dir.exists());
}
}
use str;
do run_in_mt_newsched_task {
let dir = &Path::new("./tmp/di_readdir");
- dir.mkdir();
+ mkdir(dir, io::UserRWX);
let prefix = "foo";
for n in range(0,3) {
let f = dir.join(format!("{}.txt", n));
- let mut w = f.open_writer(Create);
+ let mut w = create(&f);
let msg_str = (prefix + n.to_str().to_owned()).to_owned();
let msg = msg_str.as_bytes();
w.write(msg);
}
- match dir.readdir() {
- Some(files) => {
- let mut mem = [0u8, .. 4];
- for f in files.iter() {
- {
- let n = f.filestem_str();
- let mut r = f.open_reader(Open);
- r.read(mem);
- let read_str = str::from_utf8(mem);
- let expected = match n {
- None|Some("") => fail!("really shouldn't happen.."),
- Some(n) => prefix+n
- };
- assert!(expected == read_str);
- }
- f.unlink();
- }
- },
- None => fail!("shouldn't happen")
+ let files = readdir(dir);
+ let mut mem = [0u8, .. 4];
+ for f in files.iter() {
+ {
+ let n = f.filestem_str();
+ open(f).read(mem);
+ let read_str = str::from_utf8(mem);
+ let expected = match n {
+ None|Some("") => fail!("really shouldn't happen.."),
+ Some(n) => prefix+n
+ };
+ assert!(expected == read_str);
+ }
+ unlink(f);
}
- dir.rmdir();
+ rmdir(dir);
}
}
+
+ #[test]
+ fn recursive_mkdir_slash() {
+ mkdir_recursive(&Path::new("/"), io::UserRWX);
+ }
+
+ #[test]
+ fn unicode_path_is_dir() {
+ assert!(Path::new(".").is_dir());
+ assert!(!Path::new("test/stdtest/fs.rs").is_dir());
+
+ let tmpdir = tmpdir();
+
+ let mut dirpath = tmpdir.clone();
+ dirpath.push(format!("test-가一ー你好"));
+ mkdir(&dirpath, io::UserRWX);
+ assert!(dirpath.is_dir());
+
+ let mut filepath = dirpath;
+ filepath.push("unicode-file-\uac00\u4e00\u30fc\u4f60\u597d.rs");
+ create(&filepath); // ignore return; touch only
+ assert!(!filepath.is_dir());
+ assert!(filepath.exists());
+
+ rmdir_recursive(&tmpdir);
+ }
+
+ #[test]
+ fn unicode_path_exists() {
+ assert!(Path::new(".").exists());
+ assert!(!Path::new("test/nonexistent-bogus-path").exists());
+
+ let tmpdir = tmpdir();
+ let unicode = tmpdir.clone();
+ let unicode = unicode.join(format!("test-각丁ー再见"));
+ mkdir(&unicode, io::UserRWX);
+ assert!(unicode.exists());
+ assert!(!Path::new("test/unicode-bogus-path-각丁ー再见").exists());
+ rmdir_recursive(&tmpdir);
+ }
+
+ #[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(|| copy(&from, &to)) {
+ Ok(*) => fail!(),
+ Err(*) => {
+ assert!(!from.exists());
+ assert!(!to.exists());
+ }
+ }
+ }
+
+ #[test]
+ fn copy_file_ok() {
+ let tmpdir = tmpdir();
+ let input = tmpdir.join("in.txt");
+ let out = tmpdir.join("out.txt");
+
+ create(&input).write(bytes!("hello"));
+ copy(&input, &out);
+ let contents = open(&out).read_to_end();
+ assert_eq!(contents.as_slice(), bytes!("hello"));
+
+ assert_eq!(input.stat().mode, out.stat().mode);
+ rmdir_recursive(&tmpdir);
+ }
}
use cast;
use int;
+use libc;
use path::Path;
-use prelude::*;
use str::{StrSlice, OwnedStr};
+use option::{Option, Some, None};
+use result::{Ok, Err, Result};
+use iter::Iterator;
use to_str::ToStr;
use uint;
use unstable::finally::Finally;
}
}
+/// Helper for catching an I/O error and wrapping it in a Result object. The
+/// return result will be the last I/O error that happened or the result of the
+/// closure if no error occurred.
+pub fn result<T>(cb: &fn() -> T) -> Result<T, IoError> {
+ let mut err = None;
+ let ret = io_error::cond.trap(|e| err = Some(e)).inside(cb);
+ match err {
+ Some(e) => Err(e),
+ None => Ok(ret),
+ }
+}
+
pub trait Reader {
// Only two methods which need to get implemented for this trait
/// platform-dependent msecs
accessed: u64,
}
+
+// FIXME(#10131): this needs to get designed for real
+pub type FilePermission = u32;
+pub static UserRWX: FilePermission = libc::S_IRWXU as FilePermission;
}
}
}
+
+// n.b. these functions were all part of the old `std::os` module. There's lots
+// of fun little nuances that were taken care of by these functions, but
+// they are all thread-blocking versions that are no longer desired (we now
+// use a non-blocking event loop implementation backed by libuv).
+//
+// In theory we will have a thread-blocking version of the event loop (if
+// desired), so these functions may just need to get adapted to work in
+// those situtations. For now, I'm leaving the code around so it doesn't
+// get bitrotted instantaneously.
+mod old_os {
+ use prelude::*;
+ use c_str::CString;
+ use libc::fclose;
+ use libc::{size_t, c_void, c_int};
+ use libc;
+ use vec;
+
+ #[cfg(test)] use os;
+ #[cfg(test)] use rand;
+
+ // On Windows, wide character version of function must be used to support
+ // unicode, so functions should be split into at least two versions,
+ // which are for Windows and for non-Windows, if necessary.
+ // See https://github.com/mozilla/rust/issues/9822 for more information.
+
+ mod rustrt {
+ use libc::{c_char, c_int};
+ use libc;
+
+ extern {
+ pub fn rust_path_is_dir(path: *libc::c_char) -> c_int;
+ pub fn rust_path_exists(path: *libc::c_char) -> c_int;
+ }
+
+ // Uses _wstat instead of stat.
+ #[cfg(windows)]
+ extern {
+ pub fn rust_path_is_dir_u16(path: *u16) -> c_int;
+ pub fn rust_path_exists_u16(path: *u16) -> c_int;
+ }
+ }
+
+ /// Recursively walk a directory structure
+ pub fn walk_dir(p: &Path, f: &fn(&Path) -> bool) -> bool {
+ let r = list_dir(p);
+ r.iter().advance(|q| {
+ let path = &p.join(q);
+ f(path) && (!path_is_dir(path) || walk_dir(path, |p| f(p)))
+ })
+ }
+
+ #[cfg(unix)]
+ /// Indicates whether a path represents a directory
+ pub fn path_is_dir(p: &Path) -> bool {
+ #[fixed_stack_segment]; #[inline(never)];
+ unsafe {
+ do p.with_c_str |buf| {
+ rustrt::rust_path_is_dir(buf) != 0 as c_int
+ }
+ }
+ }
+
+
+ #[cfg(windows)]
+ pub fn path_is_dir(p: &Path) -> bool {
+ #[fixed_stack_segment]; #[inline(never)];
+ unsafe {
+ do os::win32::as_utf16_p(p.as_str().unwrap()) |buf| {
+ rustrt::rust_path_is_dir_u16(buf) != 0 as c_int
+ }
+ }
+ }
+
+ #[cfg(unix)]
+ /// Indicates whether a path exists
+ pub fn path_exists(p: &Path) -> bool {
+ #[fixed_stack_segment]; #[inline(never)];
+ unsafe {
+ do p.with_c_str |buf| {
+ rustrt::rust_path_exists(buf) != 0 as c_int
+ }
+ }
+ }
+
+ #[cfg(windows)]
+ pub fn path_exists(p: &Path) -> bool {
+ #[fixed_stack_segment]; #[inline(never)];
+ unsafe {
+ do os::win32::as_utf16_p(p.as_str().unwrap()) |buf| {
+ rustrt::rust_path_exists_u16(buf) != 0 as c_int
+ }
+ }
+ }
+
+ /// Creates a directory at the specified path
+ pub fn make_dir(p: &Path, mode: c_int) -> bool {
+ return mkdir(p, mode);
+
+ #[cfg(windows)]
+ fn mkdir(p: &Path, _mode: c_int) -> bool {
+ #[fixed_stack_segment]; #[inline(never)];
+ unsafe {
+ use os::win32::as_utf16_p;
+ // FIXME: turn mode into something useful? #2623
+ do as_utf16_p(p.as_str().unwrap()) |buf| {
+ libc::CreateDirectoryW(buf, ptr::mut_null())
+ != (0 as libc::BOOL)
+ }
+ }
+ }
+
+ #[cfg(unix)]
+ fn mkdir(p: &Path, mode: c_int) -> bool {
+ #[fixed_stack_segment]; #[inline(never)];
+ do p.with_c_str |buf| {
+ unsafe {
+ libc::mkdir(buf, mode as libc::mode_t) == (0 as c_int)
+ }
+ }
+ }
+ }
+
+ /// Creates a directory with a given mode.
+ /// Returns true iff creation
+ /// succeeded. Also creates all intermediate subdirectories
+ /// if they don't already exist, giving all of them the same mode.
+
+ // tjc: if directory exists but with different permissions,
+ // should we return false?
+ pub fn mkdir_recursive(p: &Path, mode: c_int) -> bool {
+ if path_is_dir(p) {
+ return true;
+ }
+ if p.filename().is_some() {
+ let mut p_ = p.clone();
+ p_.pop();
+ if !mkdir_recursive(&p_, mode) {
+ return false;
+ }
+ }
+ return make_dir(p, mode);
+ }
+
+ /// Lists the contents of a directory
+ ///
+ /// Each resulting Path is a relative path with no directory component.
+ pub fn list_dir(p: &Path) -> ~[Path] {
+ unsafe {
+ #[cfg(target_os = "linux")]
+ #[cfg(target_os = "android")]
+ #[cfg(target_os = "freebsd")]
+ #[cfg(target_os = "macos")]
+ unsafe fn get_list(p: &Path) -> ~[Path] {
+ #[fixed_stack_segment]; #[inline(never)];
+ use libc::{dirent_t};
+ use libc::{opendir, readdir, closedir};
+ extern {
+ fn rust_list_dir_val(ptr: *dirent_t) -> *libc::c_char;
+ }
+ let mut paths = ~[];
+ debug!("os::list_dir -- BEFORE OPENDIR");
+
+ let dir_ptr = do p.with_c_str |buf| {
+ opendir(buf)
+ };
+
+ if (dir_ptr as uint != 0) {
+ debug!("os::list_dir -- opendir() SUCCESS");
+ let mut entry_ptr = readdir(dir_ptr);
+ while (entry_ptr as uint != 0) {
+ let cstr = CString::new(rust_list_dir_val(entry_ptr), false);
+ paths.push(Path::new(cstr));
+ entry_ptr = readdir(dir_ptr);
+ }
+ closedir(dir_ptr);
+ }
+ else {
+ debug!("os::list_dir -- opendir() FAILURE");
+ }
+ debug!("os::list_dir -- AFTER -- \\#: {}", paths.len());
+ paths
+ }
+ #[cfg(windows)]
+ unsafe fn get_list(p: &Path) -> ~[Path] {
+ #[fixed_stack_segment]; #[inline(never)];
+ use libc::consts::os::extra::INVALID_HANDLE_VALUE;
+ use libc::{wcslen, free};
+ use libc::funcs::extra::kernel32::{
+ FindFirstFileW,
+ FindNextFileW,
+ FindClose,
+ };
+ use libc::types::os::arch::extra::HANDLE;
+ use os::win32::{
+ as_utf16_p
+ };
+ use rt::global_heap::malloc_raw;
+
+ #[nolink]
+ extern {
+ fn rust_list_dir_wfd_size() -> libc::size_t;
+ fn rust_list_dir_wfd_fp_buf(wfd: *libc::c_void) -> *u16;
+ }
+ let star = p.join("*");
+ do as_utf16_p(star.as_str().unwrap()) |path_ptr| {
+ let mut paths = ~[];
+ let wfd_ptr = malloc_raw(rust_list_dir_wfd_size() as uint);
+ let find_handle = FindFirstFileW(path_ptr, wfd_ptr as HANDLE);
+ if find_handle as libc::c_int != INVALID_HANDLE_VALUE {
+ let mut more_files = 1 as libc::c_int;
+ while more_files != 0 {
+ let fp_buf = rust_list_dir_wfd_fp_buf(wfd_ptr);
+ if fp_buf as uint == 0 {
+ fail!("os::list_dir() failure: got null ptr from wfd");
+ }
+ else {
+ let fp_vec = vec::from_buf(
+ fp_buf, wcslen(fp_buf) as uint);
+ let fp_str = str::from_utf16(fp_vec);
+ paths.push(Path::new(fp_str));
+ }
+ more_files = FindNextFileW(find_handle, wfd_ptr as HANDLE);
+ }
+ FindClose(find_handle);
+ free(wfd_ptr)
+ }
+ paths
+ }
+ }
+ do get_list(p).move_iter().filter |path| {
+ path.as_vec() != bytes!(".") && path.as_vec() != bytes!("..")
+ }.collect()
+ }
+ }
+
+ /// Removes a directory at the specified path, after removing
+ /// all its contents. Use carefully!
+ pub fn remove_dir_recursive(p: &Path) -> bool {
+ let mut error_happened = false;
+ do walk_dir(p) |inner| {
+ if !error_happened {
+ if path_is_dir(inner) {
+ if !remove_dir_recursive(inner) {
+ error_happened = true;
+ }
+ }
+ else {
+ if !remove_file(inner) {
+ error_happened = true;
+ }
+ }
+ }
+ true
+ };
+ // Directory should now be empty
+ !error_happened && remove_dir(p)
+ }
+
+ /// Removes a directory at the specified path
+ pub fn remove_dir(p: &Path) -> bool {
+ return rmdir(p);
+
+ #[cfg(windows)]
+ fn rmdir(p: &Path) -> bool {
+ #[fixed_stack_segment]; #[inline(never)];
+ unsafe {
+ use os::win32::as_utf16_p;
+ return do as_utf16_p(p.as_str().unwrap()) |buf| {
+ libc::RemoveDirectoryW(buf) != (0 as libc::BOOL)
+ };
+ }
+ }
+
+ #[cfg(unix)]
+ fn rmdir(p: &Path) -> bool {
+ #[fixed_stack_segment]; #[inline(never)];
+ do p.with_c_str |buf| {
+ unsafe {
+ libc::rmdir(buf) == (0 as c_int)
+ }
+ }
+ }
+ }
+
+ /// Deletes an existing file
+ pub fn remove_file(p: &Path) -> bool {
+ return unlink(p);
+
+ #[cfg(windows)]
+ fn unlink(p: &Path) -> bool {
+ #[fixed_stack_segment]; #[inline(never)];
+ unsafe {
+ use os::win32::as_utf16_p;
+ return do as_utf16_p(p.as_str().unwrap()) |buf| {
+ libc::DeleteFileW(buf) != (0 as libc::BOOL)
+ };
+ }
+ }
+
+ #[cfg(unix)]
+ fn unlink(p: &Path) -> bool {
+ #[fixed_stack_segment]; #[inline(never)];
+ unsafe {
+ do p.with_c_str |buf| {
+ libc::unlink(buf) == (0 as c_int)
+ }
+ }
+ }
+ }
+
+ /// Renames an existing file or directory
+ pub fn rename_file(old: &Path, new: &Path) -> bool {
+ #[fixed_stack_segment]; #[inline(never)];
+ unsafe {
+ do old.with_c_str |old_buf| {
+ do new.with_c_str |new_buf| {
+ libc::rename(old_buf, new_buf) == (0 as c_int)
+ }
+ }
+ }
+ }
+
+ /// Copies a file from one location to another
+ pub fn copy_file(from: &Path, to: &Path) -> bool {
+ return do_copy_file(from, to);
+
+ #[cfg(windows)]
+ fn do_copy_file(from: &Path, to: &Path) -> bool {
+ #[fixed_stack_segment]; #[inline(never)];
+ unsafe {
+ use os::win32::as_utf16_p;
+ return do as_utf16_p(from.as_str().unwrap()) |fromp| {
+ do as_utf16_p(to.as_str().unwrap()) |top| {
+ libc::CopyFileW(fromp, top, (0 as libc::BOOL)) !=
+ (0 as libc::BOOL)
+ }
+ }
+ }
+ }
+
+ #[cfg(unix)]
+ fn do_copy_file(from: &Path, to: &Path) -> bool {
+ #[fixed_stack_segment]; #[inline(never)];
+ unsafe {
+ let istream = do from.with_c_str |fromp| {
+ do "rb".with_c_str |modebuf| {
+ libc::fopen(fromp, modebuf)
+ }
+ };
+ if istream as uint == 0u {
+ return false;
+ }
+ // Preserve permissions
+ let from_mode = from.stat().mode;
+
+ let ostream = do to.with_c_str |top| {
+ do "w+b".with_c_str |modebuf| {
+ libc::fopen(top, modebuf)
+ }
+ };
+ if ostream as uint == 0u {
+ fclose(istream);
+ return false;
+ }
+ let bufsize = 8192u;
+ let mut buf = vec::with_capacity::<u8>(bufsize);
+ let mut done = false;
+ let mut ok = true;
+ while !done {
+ do buf.as_mut_buf |b, _sz| {
+ let nread = libc::fread(b as *mut c_void, 1u as size_t,
+ bufsize as size_t,
+ istream);
+ if nread > 0 as size_t {
+ if libc::fwrite(b as *c_void, 1u as size_t, nread,
+ ostream) != nread {
+ ok = false;
+ done = true;
+ }
+ } else {
+ done = true;
+ }
+ }
+ }
+ fclose(istream);
+ fclose(ostream);
+
+ // Give the new file the old file's permissions
+ if do to.with_c_str |to_buf| {
+ libc::chmod(to_buf, from_mode as libc::mode_t)
+ } != 0 {
+ return false; // should be a condition...
+ }
+ return ok;
+ }
+ }
+ }
+
+ #[test]
+ fn tmpdir() {
+ let p = os::tmpdir();
+ let s = p.as_str();
+ assert!(s.is_some() && s.unwrap() != ".");
+ }
+
+ // Issue #712
+ #[test]
+ fn test_list_dir_no_invalid_memory_access() {
+ list_dir(&Path::new("."));
+ }
+
+ #[test]
+ fn test_list_dir() {
+ let dirs = list_dir(&Path::new("."));
+ // Just assuming that we've got some contents in the current directory
+ assert!(dirs.len() > 0u);
+
+ for dir in dirs.iter() {
+ debug!("{:?}", (*dir).clone());
+ }
+ }
+
+ #[test]
+ #[cfg(not(windows))]
+ fn test_list_dir_root() {
+ let dirs = list_dir(&Path::new("/"));
+ assert!(dirs.len() > 1);
+ }
+ #[test]
+ #[cfg(windows)]
+ fn test_list_dir_root() {
+ let dirs = list_dir(&Path::new("C:\\"));
+ assert!(dirs.len() > 1);
+ }
+
+ #[test]
+ fn test_path_is_dir() {
+ use rt::io::file::{open_stream, mkdir_recursive};
+ use rt::io::{OpenOrCreate, Read, UserRWX};
+
+ assert!((path_is_dir(&Path::new("."))));
+ assert!((!path_is_dir(&Path::new("test/stdtest/fs.rs"))));
+
+ let mut dirpath = os::tmpdir();
+ dirpath.push(format!("rust-test-{}/test-\uac00\u4e00\u30fc\u4f60\u597d",
+ rand::random::<u32>())); // 가一ー你好
+ debug!("path_is_dir dirpath: {}", dirpath.display());
+
+ mkdir_recursive(&dirpath, UserRWX);
+
+ assert!((path_is_dir(&dirpath)));
+
+ let mut filepath = dirpath;
+ filepath.push("unicode-file-\uac00\u4e00\u30fc\u4f60\u597d.rs");
+ debug!("path_is_dir filepath: {}", filepath.display());
+
+ open_stream(&filepath, OpenOrCreate, Read); // ignore return; touch only
+ assert!((!path_is_dir(&filepath)));
+
+ assert!((!path_is_dir(&Path::new(
+ "test/unicode-bogus-dir-\uac00\u4e00\u30fc\u4f60\u597d"))));
+ }
+
+ #[test]
+ fn test_path_exists() {
+ use rt::io::file::mkdir_recursive;
+ use rt::io::UserRWX;
+
+ assert!((path_exists(&Path::new("."))));
+ assert!((!path_exists(&Path::new(
+ "test/nonexistent-bogus-path"))));
+
+ let mut dirpath = os::tmpdir();
+ dirpath.push(format!("rust-test-{}/test-\uac01\u4e01\u30fc\u518d\u89c1",
+ rand::random::<u32>())); // 각丁ー再见
+
+ mkdir_recursive(&dirpath, UserRWX);
+ assert!((path_exists(&dirpath)));
+ assert!((!path_exists(&Path::new(
+ "test/unicode-bogus-path-\uac01\u4e01\u30fc\u518d\u89c1"))));
+ }
+}
use rt::test::*;
use rt::io::*;
use rt::comm::oneshot;
- use os;
fn smalltest(server: ~fn(UnixStream), client: ~fn(UnixStream)) {
let server = Cell::new(server);
do run_in_mt_newsched_task {
let path = next_test_unix();
let _acceptor = UnixListener::bind(&path).listen();
- assert!(os::path_exists(&path));
+ assert!(path.exists());
}
}
}
*/
+use container::{Map, MutableMap};
use comm::{Port, SharedChan, stream};
use hashmap;
use option::{Some, None};
#[cfg(test)]
mod test {
- use super::*;
-
use libc;
use rt::io::timer;
+ use super::{Listener, Interrupt};
+ use comm::{GenericPort, Peekable};
// kill is only available on Unixes
#[cfg(unix)]
#[cfg(windows)]
#[test]
fn test_io_signal_invalid_signum() {
- use rt::io;
+ use super::User1;
let mut s = Listener::new();
let mut called = false;
do io::io_error::cond.trap(|_| {
#[cfg(test)]
mod test {
+ use prelude::*;
use super::*;
use rt::test::*;
use cell::Cell;
use super::io::net::ip::{IpAddr, SocketAddr};
use path::Path;
use super::io::{SeekStyle};
-use super::io::{FileMode, FileAccess, FileStat};
+use super::io::{FileMode, FileAccess, FileStat, FilePermission};
pub trait EventLoop {
fn run(&mut self);
-> Result<~RtioFileStream, IoError>;
fn fs_unlink(&mut self, path: &CString) -> Result<(), IoError>;
fn fs_stat(&mut self, path: &CString) -> Result<FileStat, IoError>;
- fn fs_mkdir(&mut self, path: &CString, mode: int) -> Result<(), IoError>;
+ fn fs_mkdir(&mut self, path: &CString,
+ mode: FilePermission) -> Result<(), IoError>;
+ fn fs_chmod(&mut self, path: &CString,
+ mode: FilePermission) -> Result<(), IoError>;
fn fs_rmdir(&mut self, path: &CString) -> Result<(), IoError>;
fn fs_rename(&mut self, path: &CString, to: &CString) -> Result<(), IoError>;
fn fs_readdir(&mut self, path: &CString, flags: c_int) ->
let parent_dir = os::getcwd();
let child_dir = Path::new(output.trim());
- let parent_stat = parent_dir.stat().unwrap();
- let child_stat = child_dir.stat().unwrap();
+ 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);
let output = str::from_utf8(prog.finish_with_output().output);
let child_dir = Path::new(output.trim());
- let parent_stat = parent_dir.stat().unwrap();
- let child_stat = child_dir.stat().unwrap();
+ 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);
use std::rt::io;
use std::rt::io::Reader;
-use std::rt::io::file::FileInfo;
+use std::rt::io::file;
use std::str;
// These macros all relate to the file system; they either return
-> base::MacResult {
let file = get_single_str_from_tts(cx, sp, tts, "include_str!");
let file = res_rel_file(cx, sp, &Path::new(file));
- let mut error = None;
- let bytes = do io::io_error::cond.trap(|e| error = Some(e)).inside {
- file.open_reader(io::Open).read_to_end()
- };
- match error {
- Some(e) => {
+ let bytes = match io::result(|| file::open(&file).read_to_end()) {
+ Err(e) => {
cx.span_fatal(sp, format!("couldn't read {}: {}",
file.display(), e.desc));
}
- None => {}
- }
+ Ok(bytes) => bytes,
+ };
match str::from_utf8_owned_opt(bytes) {
Some(s) => base::MRExpr(cx.expr_str(sp, s.to_managed())),
None => {
let file = get_single_str_from_tts(cx, sp, tts, "include_bin!");
let file = res_rel_file(cx, sp, &Path::new(file));
-
- let mut error = None;
- let bytes = do io::io_error::cond.trap(|e| error = Some(e)).inside {
- file.open_reader(io::Open).read_to_end()
- };
- match error {
- Some(e) => {
+ match io::result(|| file::open(&file).read_to_end()) {
+ Err(e) => {
cx.span_fatal(sp, format!("couldn't read {}: {}",
file.display(), e.desc));
}
- None => {
+ Ok(bytes) => {
let bytes = at_vec::to_managed_move(bytes);
base::MRExpr(cx.expr_lit(sp, ast::lit_binary(bytes)))
}
use std::path::Path;
use std::rt::io;
-use std::rt::io::Reader;
-use std::rt::io::file::FileInfo;
+use std::rt::io::file;
use std::str;
pub mod lexer;
None => sess.span_diagnostic.handler().fatal(msg),
}
};
- let mut error = None;
- let bytes = do io::io_error::cond.trap(|e| error = Some(e)).inside {
- path.open_reader(io::Open).read_to_end()
- };
- match error {
- Some(e) => {
+ let bytes = match io::result(|| file::open(path).read_to_end()) {
+ Ok(bytes) => bytes,
+ Err(e) => {
err(format!("couldn't read {}: {}", path.display(), e.desc));
+ unreachable!()
}
- None => {}
- }
+ };
match str::from_utf8_owned_opt(bytes) {
Some(s) => {
return string_to_filemap(sess, s.to_managed(),
const char *to, uv_fs_cb cb) {
return uv_fs_rename(loop, req, path, to, cb);
}
+extern "C" int
+rust_uv_fs_chmod(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode, uv_fs_cb cb) {
+ return uv_fs_chmod(loop, req, path, mode, cb);
+}
extern "C" int
rust_uv_spawn(uv_loop_t *loop, uv_process_t *p, uv_process_options_t options) {
use std::str;
use std::util;
use std::vec;
+use std::rt::io::file;
macro_rules! bench (
($argv:expr, $id:ident) => (maybe_run_test($argv, stringify!($id).to_owned(), $id))
}
fn read_line() {
- use std::rt::io::{Reader, Open};
- use std::rt::io::file::FileInfo;
use std::rt::io::buffered::BufferedReader;
let mut path = Path::new(env!("CFG_SRC_DIR"));
path.push("src/test/bench/shootout-k-nucleotide.data");
for _ in range(0, 3) {
- let mut reader = BufferedReader::new(path.open_reader(Open).unwrap());
+ let mut reader = BufferedReader::new(file::open(&path).unwrap());
while !reader.eof() {
reader.read_line();
}
use std::int;
use std::rt::io;
+use std::rt::io::file;
use std::os;
use std::rand::Rng;
use std::rand;
}
fn main() {
- use std::rt::io::file::FileInfo;
let args = os::args();
let args = if os::getenv("RUST_BENCH").is_some() {
// alioth tests k-nucleotide with this data at 25,000,000
};
let writer = if os::getenv("RUST_BENCH").is_some() {
- let file = Path::new("./shootout-fasta.data").open_writer(io::CreateOrTruncate);
+ let file = file::create(&Path::new("./shootout-fasta.data"));
@mut file as @mut io::Writer
} else {
@mut io::stdout() as @mut io::Writer
// except according to those terms.
// xfail-pretty
+// xfail-test
extern mod extra;
extern mod syntax;
// option. This file may not be copied, modified, or distributed
// except according to those terms.
+// xfail-test
+
+#[feature(managed_boxes)];
+
extern mod syntax;
use syntax::ext::base::ExtCtxt;
let e_toks : ~[syntax::ast::token_tree] = quote_tokens!(cx, 1 + 2);
let p_toks : ~[syntax::ast::token_tree] = quote_tokens!(cx, (x, 1 .. 4, *));
- let a: @syntax::ast::expr = quote_expr!(cx, 1 + 2);
+ let a: @syntax::ast::Expr = quote_expr!(cx, 1 + 2);
let _b: Option<@syntax::ast::item> = quote_item!(cx, static foo : int = $e_toks; );
- let _c: @syntax::ast::pat = quote_pat!(cx, (x, 1 .. 4, *) );
- let _d: @syntax::ast::stmt = quote_stmt!(cx, let x = $a; );
- let _e: @syntax::ast::expr = quote_expr!(cx, match foo { $p_toks => 10 } );
+ let _c: @syntax::ast::Pat = quote_pat!(cx, (x, 1 .. 4, *) );
+ let _d: @syntax::ast::Stmt = quote_stmt!(cx, let x = $a; );
+ let _e: @syntax::ast::Expr = quote_expr!(cx, match foo { $p_toks => 10 } );
}
fn main() {
use std::unstable::finally::Finally;
use std::{os, unstable};
use std::rt::io;
-use std::rt::io::file::FileInfo;
pub fn main() {
fn mk_file(path: &str, directory: bool) {
if directory {
- os::make_dir(&Path::new(path), 0xFFFF);
+ io::file::mkdir(&Path::new(path), io::UserRWX);
} else {
- Path::new(path).open_writer(io::Create);
+ io::file::create(&Path::new(path));
}
}
use extra::tempfile::TempDir;
use std::os;
use std::libc;
+use std::rt::io;
+use std::rt::io::file;
fn rename_directory() {
#[fixed_stack_segment];
let tmpdir = TempDir::new("rename_directory").expect("rename_directory failed");
let tmpdir = tmpdir.path();
let old_path = tmpdir.join_many(["foo", "bar", "baz"]);
- assert!(os::mkdir_recursive(&old_path, U_RWX));
+ file::mkdir_recursive(&old_path, io::UserRWX);
let test_file = &old_path.join("temp.txt");
/* Write the temp input file */
assert_eq!(libc::fclose(ostream), (0u as libc::c_int));
let new_path = tmpdir.join_many(["quux", "blat"]);
- assert!(os::mkdir_recursive(&new_path, U_RWX));
- assert!(os::rename_file(&old_path, &new_path.join("newdir")));
- assert!(os::path_is_dir(&new_path.join("newdir")));
- assert!(os::path_exists(&new_path.join_many(["newdir", "temp.txt"])));
+ file::mkdir_recursive(&new_path, io::UserRWX);
+ file::rename(&old_path, &new_path.join("newdir"));
+ assert!(new_path.join("newdir").is_dir());
+ assert!(new_path.join_many(["newdir", "temp.txt"]).exists());
}
}
extern mod extra;
use extra::tempfile;
-use std::rt::io;
-use std::rt::io::Writer;
-use std::rt::io::file::FileInfo;
-use std::os;
+use std::rt::io::file;
pub fn main() {
let dir = tempfile::TempDir::new_in(&Path::new("."), "").unwrap();
let path = dir.path().join("file");
{
- match path.open_writer(io::CreateOrTruncate) {
+ match file::create(&path) {
None => unreachable!(),
Some(f) => {
let mut f = f;
}
assert!(path.exists());
- assert_eq!(path.get_size(), Some(1000));
+ assert_eq!(path.stat().size, 1000);
}
use extra::tempfile::TempDir;
use std::os;
-use std::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR};
use std::task;
use std::cell::Cell;
+use std::rt::io;
+use std::rt::io::file;
fn test_tempdir() {
let path = {
assert!(p.as_vec().ends_with(bytes!("foobar")));
p.clone()
};
- assert!(!os::path_exists(&path));
+ assert!(!path.exists());
}
fn test_rm_tempdir() {
};
task::try(f);
let path = rd.recv();
- assert!(!os::path_exists(&path));
+ assert!(!path.exists());
let tmp = TempDir::new("test_rm_tempdir").unwrap();
let path = tmp.path().clone();
fail!("fail to unwind past `tmp`");
};
task::try(f);
- assert!(!os::path_exists(&path));
+ assert!(!path.exists());
let path;
{
};
let tmp = task::try(f).expect("test_rm_tmdir");
path = tmp.path().clone();
- assert!(os::path_exists(&path));
+ assert!(path.exists());
}
- assert!(!os::path_exists(&path));
+ assert!(!path.exists());
let path;
{
let tmp = TempDir::new("test_rm_tempdir").unwrap();
path = tmp.unwrap();
}
- assert!(os::path_exists(&path));
- os::remove_dir_recursive(&path);
- assert!(!os::path_exists(&path));
+ assert!(path.exists());
+ file::rmdir_recursive(&path);
+ assert!(!path.exists());
}
// Ideally these would be in std::os but then core would need
let path = Path::new("frob");
let cwd = os::getcwd();
debug!("recursive_mkdir_rel: Making: {} in cwd {} [{:?}]", path.display(),
- cwd.display(), os::path_exists(&path));
- assert!(os::mkdir_recursive(&path, (S_IRUSR | S_IWUSR | S_IXUSR) as i32));
- assert!(os::path_is_dir(&path));
- assert!(os::mkdir_recursive(&path, (S_IRUSR | S_IWUSR | S_IXUSR) as i32));
- assert!(os::path_is_dir(&path));
+ cwd.display(), path.exists());
+ file::mkdir_recursive(&path, io::UserRWX);
+ assert!(path.is_dir());
+ file::mkdir_recursive(&path, io::UserRWX);
+ assert!(path.is_dir());
}
fn recursive_mkdir_dot() {
let dot = Path::new(".");
- assert!(os::mkdir_recursive(&dot, (S_IRUSR | S_IWUSR | S_IXUSR) as i32));
+ file::mkdir_recursive(&dot, io::UserRWX);
let dotdot = Path::new("..");
- assert!(os::mkdir_recursive(&dotdot, (S_IRUSR | S_IWUSR | S_IXUSR) as i32));
+ file::mkdir_recursive(&dotdot, io::UserRWX);
}
fn recursive_mkdir_rel_2() {
let path = Path::new("./frob/baz");
let cwd = os::getcwd();
debug!("recursive_mkdir_rel_2: Making: {} in cwd {} [{:?}]", path.display(),
- cwd.display(), os::path_exists(&path));
- assert!(os::mkdir_recursive(&path, (S_IRUSR | S_IWUSR | S_IXUSR) as i32));
- assert!(os::path_is_dir(&path));
- assert!(os::path_is_dir(&path.dir_path()));
+ cwd.display(), path.exists());
+ file::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());
- assert!(os::mkdir_recursive(&path2, (S_IRUSR | S_IWUSR | S_IXUSR) as i32));
- assert!(os::path_is_dir(&path2));
- assert!(os::path_is_dir(&path2.dir_path()));
+ file::mkdir_recursive(&path2, io::UserRWX);
+ assert!(path2.is_dir());
+ assert!(path2.dir_path().is_dir());
}
// Ideally this would be in core, but needs TempFile
pub fn test_rmdir_recursive_ok() {
- let rwx = (S_IRUSR | S_IWUSR | S_IXUSR) as i32;
+ let rwx = io::UserRWX;
let tmpdir = TempDir::new("test").expect("test_rmdir_recursive_ok: \
couldn't create temp dir");
let root = tmpdir.join("foo");
debug!("making {}", root.display());
- assert!(os::make_dir(&root, rwx));
- assert!(os::make_dir(&root.join("foo"), rwx));
- assert!(os::make_dir(&root.join("foo").join("bar"), rwx));
- assert!(os::make_dir(&root.join("foo").join("bar").join("blat"), rwx));
- assert!(os::remove_dir_recursive(&root));
- assert!(!os::path_exists(&root));
- assert!(!os::path_exists(&root.join("bar")));
- assert!(!os::path_exists(&root.join("bar").join("blat")));
+ 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);
+ assert!(!root.exists());
+ assert!(!root.join("bar").exists());
+ assert!(!root.join("bar").join("blat").exists());
}
fn in_tmpdir(f: &fn()) {