Fill out the remaining functionality in io::file

This adds bindings to the remaining functions provided by libuv, all of which
are useful operations on files which need to get exposed somehow.

Some highlights:

* Dropped `FileReader` and `FileWriter` and `FileStream` for one `File` type
* Moved all file-related methods to be static methods under `File`
* All directory related methods are still top-level functions
* Created `io::FilePermission` types (backed by u32) that are what you'd expect
* Created `io::FileType` and refactored `FileStat` to use FileType and
  FilePermission
* Removed the expanding matrix of `FileMode` operations. The mode of reading a
  file will not have the O_CREAT flag, but a write mode will always have the
  O_CREAT flag.

Closes #10130
Closes #10131
Closes #10121
This commit is contained in:
Alex Crichton 2013-10-29 23:31:07 -07:00
parent 9c1851019f
commit f19d083362
38 changed files with 1381 additions and 1030 deletions

View File

@ -9,7 +9,7 @@
// except according to those terms.
use std::rt::io::buffered::BufferedReader;
use std::rt::io::file;
use std::rt::io::File;
pub struct ExpectedError { line: uint, kind: ~str, msg: ~str }
@ -17,7 +17,7 @@ pub struct ExpectedError { line: uint, kind: ~str, msg: ~str }
pub fn load_errors(testfile: &Path) -> ~[ExpectedError] {
let mut error_patterns = ~[];
let mut rdr = BufferedReader::new(file::open(testfile).unwrap());
let mut rdr = BufferedReader::new(File::open(testfile).unwrap());
let mut line_num = 1u;
loop {
let ln = match rdr.read_line() {

View File

@ -104,9 +104,9 @@ pub fn is_test_ignored(config: &config, testfile: &Path) -> bool {
fn iter_header(testfile: &Path, it: &fn(&str) -> bool) -> bool {
use std::rt::io::buffered::BufferedReader;
use std::rt::io::file;
use std::rt::io::File;
let mut rdr = BufferedReader::new(file::open(testfile).unwrap());
let mut rdr = BufferedReader::new(File::open(testfile).unwrap());
loop {
let ln = match rdr.read_line() {
Some(ln) => ln, None => break

View File

@ -23,6 +23,7 @@ use util::logv;
use std::cell::Cell;
use std::rt::io;
use std::rt::io::file;
use std::rt::io::File;
use std::os;
use std::str;
use std::task::{spawn_sched, SingleThreaded};
@ -171,7 +172,7 @@ fn run_pretty_test(config: &config, props: &TestProps, testfile: &Path) {
let rounds =
match props.pp_exact { Some(_) => 1, None => 2 };
let src = file::open(testfile).read_to_end();
let src = File::open(testfile).read_to_end();
let src = str::from_utf8_owned(src);
let mut srcs = ~[src];
@ -193,7 +194,7 @@ fn run_pretty_test(config: &config, props: &TestProps, testfile: &Path) {
let mut expected = match props.pp_exact {
Some(ref file) => {
let filepath = testfile.dir_path().join(file);
let s = file::open(&filepath).read_to_end();
let s = File::open(&filepath).read_to_end();
str::from_utf8_owned(s)
}
None => { srcs[srcs.len() - 2u].clone() }
@ -764,7 +765,7 @@ fn dump_output(config: &config, testfile: &Path, out: &str, err: &str) {
fn dump_output_file(config: &config, testfile: &Path,
out: &str, extension: &str) {
let outfile = make_out_name(config, testfile, extension);
file::create(&outfile).write(out.as_bytes());
File::create(&outfile).write(out.as_bytes());
}
fn make_out_name(config: &config, testfile: &Path, extension: &str) -> Path {
@ -1015,7 +1016,7 @@ fn disassemble_extract(config: &config, _props: &TestProps,
fn count_extracted_lines(p: &Path) -> uint {
let x = file::open(&p.with_extension("ll")).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()
}

View File

@ -143,6 +143,7 @@ void posix88_consts() {
put_const(S_IFBLK, int);
put_const(S_IFDIR, int);
put_const(S_IFREG, int);
put_const(S_IFLNK, int);
put_const(S_IFMT, int);
put_const(S_IEXEC, int);

View File

@ -14,7 +14,7 @@
use std::{os, str};
use std::os::getenv;
use std::rt::io;
use std::rt::io::file;
use std::rt::io::File;
/// Return path to database entry for `term`
pub fn get_dbpath_for_term(term: &str) -> Option<~Path> {
@ -76,7 +76,7 @@ pub fn get_dbpath_for_term(term: &str) -> Option<~Path> {
/// 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 file::open(x) 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))
}
}

View File

@ -31,7 +31,7 @@ use treemap::TreeMap;
use std::clone::Clone;
use std::comm::{stream, SharedChan, GenericPort, GenericChan};
use std::rt::io;
use std::rt::io::file;
use std::rt::io::File;
use std::task;
use std::to_str::ToStr;
use std::f64;
@ -353,7 +353,7 @@ struct ConsoleTestState {
impl ConsoleTestState {
pub fn new(opts: &TestOpts) -> ConsoleTestState {
let log_out = match opts.logfile {
Some(ref path) => Some(@mut file::create(path) 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;
@ -936,14 +936,14 @@ impl MetricMap {
/// Load MetricDiff from a file.
pub fn load(p: &Path) -> MetricMap {
assert!(p.exists());
let f = @mut file::open(p) as @mut io::Reader;
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) {
self.to_json().to_pretty_writer(@mut file::create(p) 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

View File

@ -19,7 +19,7 @@ use std::cell::Cell;
use std::comm::{PortOne, oneshot};
use std::{str, task};
use std::rt::io;
use std::rt::io::file;
use std::rt::io::File;
use std::rt::io::Decorator;
use std::rt::io::mem::MemWriter;
@ -176,14 +176,14 @@ impl Database {
// FIXME #4330: This should have &mut self and should set self.db_dirty to false.
fn save(&self) {
let f = @mut file::create(&self.db_filename);
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!(self.db_filename.exists());
match io::result(|| file::open(&self.db_filename)) {
match io::result(|| File::open(&self.db_filename)) {
Err(e) => fail!("Couldn't load workcache database {}: {}",
self.db_filename.display(),
e.desc),
@ -480,7 +480,6 @@ impl<'self, T:Send +
#[test]
fn test() {
use std::{os, run};
use std::rt::io::file;
use std::str::from_utf8_owned;
// Create a path to a new file 'filename' in the directory in which
@ -488,13 +487,13 @@ fn test() {
fn make_path(filename: ~str) -> Path {
let pth = os::self_exe_path().expect("workcache::test failed").with_filename(filename);
if pth.exists() {
file::unlink(&pth);
File::unlink(&pth);
}
return pth;
}
let pth = make_path(~"foo.c");
file::create(&pth).write(bytes!("int main() { return 0; }"));
File::create(&pth).write(bytes!("int main() { return 0; }"));
let db_path = make_path(~"db.json");
@ -507,7 +506,7 @@ fn test() {
let subcx = cx.clone();
let pth = pth.clone();
let file_content = from_utf8_owned(file::open(&pth).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);

View File

@ -31,7 +31,7 @@ use std::ptr;
use std::run;
use std::str;
use std::vec;
use std::rt::io::file;
use std::rt::io::File;
use syntax::ast;
use syntax::ast_map::{path, path_mod, path_name, path_pretty_name};
use syntax::attr;
@ -950,18 +950,17 @@ pub fn link_binary(sess: Session,
// Remove the temporary object file if we aren't saving temps
if !sess.opts.save_temps {
file::unlink(obj_filename);
File::unlink(obj_filename);
}
}
fn is_writeable(p: &Path) -> bool {
use std::rt::io;
use std::libc::consts::os::posix88::S_IWUSR;
!p.exists() ||
(match io::result(|| p.stat()) {
Err(*) => false,
Ok(m) => (m.mode as uint) & S_IWUSR as uint == S_IWUSR as uint
Ok(m) => m.perm & io::UserWrite == io::UserWrite
})
}

View File

@ -27,7 +27,7 @@ use util::ppaux;
use std::hashmap::{HashMap,HashSet};
use std::rt::io;
use std::rt::io::file;
use std::rt::io::File;
use std::rt::io::mem::MemReader;
use std::os;
use std::vec;
@ -370,7 +370,7 @@ pub fn phase_5_run_llvm_passes(sess: Session,
// Remove assembly source unless --save-temps was specified
if !sess.opts.save_temps {
file::unlink(&asm_filename);
File::unlink(&asm_filename);
}
} else {
time(sess.time_passes(), "LLVM passes", (), |_|

View File

@ -42,6 +42,7 @@ use std::local_data;
use std::rt::io::buffered::BufferedWriter;
use std::rt::io;
use std::rt::io::file;
use std::rt::io::File;
use std::os;
use std::str;
use std::task;
@ -263,7 +264,7 @@ pub fn run(mut crate: clean::Crate, dst: Path) {
// Publish the search index
{
dst.push("search-index.js");
let mut w = BufferedWriter::new(file::create(&dst).unwrap());
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() {
@ -313,7 +314,7 @@ pub fn run(mut crate: clean::Crate, dst: Path) {
/// Writes the entire contents of a string to a destination, not attempting to
/// catch any errors.
fn write(dst: Path, contents: &str) {
file::create(&dst).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
@ -419,7 +420,7 @@ impl<'self> SourceCollector<'self> {
// 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 io::result(|| file::open(&p)) {
let mut r = match io::result(|| File::open(&p)) {
Ok(r) => r,
// eew macro hacks
Err(*) => return filename == "<std-macros>"
@ -445,7 +446,7 @@ impl<'self> SourceCollector<'self> {
}
cur.push(p.filename().expect("source has no filename") + bytes!(".html"));
let mut w = BufferedWriter::new(file::create(&cur).unwrap());
let mut w = BufferedWriter::new(File::create(&cur).unwrap());
let title = cur.filename_display().with_str(|s| format!("{} -- source", s));
let page = layout::Page {
@ -767,7 +768,7 @@ impl Context {
///
/// 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: file::FileWriter, cx: &mut Context, it: &clean::Item,
fn render(w: io::File, 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.
@ -804,7 +805,7 @@ impl Context {
do self.recurse(name) |this| {
let item = item.take();
let dst = this.dst.join("index.html");
render(file::create(&dst).unwrap(), this, &item, false);
render(File::create(&dst).unwrap(), this, &item, false);
let m = match item.inner {
clean::ModuleItem(m) => m,
@ -821,7 +822,7 @@ impl Context {
// pages dedicated to them.
_ if item.name.is_some() => {
let dst = self.dst.join(item_path(&item));
render(file::create(&dst).unwrap(), self, &item, true);
render(File::create(&dst).unwrap(), self, &item, true);
}
_ => {}

View File

@ -26,7 +26,7 @@ extern mod extra;
use std::cell::Cell;
use std::local_data;
use std::rt::io;
use std::rt::io::file;
use std::rt::io::File;
use std::rt::io::mem::MemWriter;
use std::rt::io::Decorator;
use std::str;
@ -259,7 +259,7 @@ fn rust_input(cratefile: &str, matches: &getopts::Matches) -> Output {
/// 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 file::open(&Path::new(input)) {
let input = match File::open(&Path::new(input)) {
Some(f) => f,
None => return Err(format!("couldn't open {} for reading", input)),
};
@ -321,7 +321,7 @@ fn json_output(crate: clean::Crate, res: ~[plugins::PluginJson], dst: Path) {
json.insert(~"crate", crate_json);
json.insert(~"plugins", json::Object(plugins_json));
let mut file = file::create(&dst).unwrap();
let mut file = File::create(&dst).unwrap();
let output = json::Object(json).to_str();
file.write(output.as_bytes());
}

View File

@ -28,6 +28,7 @@ use std::{os, result, run, str, task};
use std::hashmap::HashSet;
use std::rt::io;
use std::rt::io::file;
use std::rt::io::File;
pub use std::path::Path;
use extra::workcache;
@ -661,7 +662,7 @@ impl CtxMethods for BuildContext {
for exec in subex.iter() {
debug!("Copying: {} -> {}", exec.display(), sub_target_ex.display());
file::mkdir_recursive(&sub_target_ex.dir_path(), io::UserRWX);
file::copy(exec, &sub_target_ex);
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(),
@ -674,7 +675,7 @@ impl CtxMethods for BuildContext {
didn't install it!", lib.display()));
target_lib.set_filename(lib.filename().expect("weird target lib"));
file::mkdir_recursive(&target_lib.dir_path(), io::UserRWX);
file::copy(lib, &target_lib);
File::copy(lib, &target_lib);
debug!("3. discovering output {}", target_lib.display());
exe_thing.discover_output("binary",
target_lib.as_str().unwrap(),

View File

@ -14,6 +14,7 @@ use target::*;
use package_id::PkgId;
use std::rt::io;
use std::rt::io::file;
use std::rt::io::File;
use std::os;
use context::*;
use crate::Crate;
@ -301,7 +302,7 @@ impl PkgSrc {
// Move clone_target to local.
// First, create all ancestor directories.
let moved = make_dir_rwx_recursive(&local.dir_path())
&& io::result(|| file::rename(&clone_target, local)).is_ok();
&& io::result(|| File::rename(&clone_target, local)).is_ok();
if moved { Some(local.clone()) }
else { None }
}
@ -350,7 +351,7 @@ impl PkgSrc {
let prefix = self.start_dir.component_iter().len();
debug!("Matching against {}", self.id.short_name);
do file::walk_dir(&self.start_dir) |pth| {
for pth in file::walk_dir(&self.start_dir) {
let maybe_known_crate_set = match pth.filename_str() {
Some(filename) if filter(filename) => match filename {
"lib.rs" => Some(&mut self.libs),
@ -363,11 +364,10 @@ impl PkgSrc {
};
match maybe_known_crate_set {
Some(crate_set) => PkgSrc::push_crate(crate_set, prefix, pth),
Some(crate_set) => PkgSrc::push_crate(crate_set, prefix, &pth),
None => ()
}
true
};
}
let crate_sets = [&self.libs, &self.mains, &self.tests, &self.benchs];
if crate_sets.iter().all(|crate_set| crate_set.is_empty()) {

View File

@ -21,6 +21,7 @@ use std::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR};
use std::os;
use std::rt::io;
use std::rt::io::file;
use std::rt::io::File;
use messages::*;
pub fn default_workspace() -> Path {
@ -72,9 +73,9 @@ pub fn workspace_contains_package_id_(pkgid: &PkgId, workspace: &Path,
if !src_dir.is_dir() { return None }
let mut found = None;
do file::walk_dir(&src_dir) |p| {
for p in file::walk_dir(&src_dir) {
if p.is_dir() {
if *p == src_dir.join(&pkgid.path) || {
if p == src_dir.join(&pkgid.path) || {
let pf = p.filename_str();
do pf.iter().any |&g| {
match split_version_general(g, '-') {
@ -89,9 +90,8 @@ pub fn workspace_contains_package_id_(pkgid: &PkgId, workspace: &Path,
found = Some(p.clone());
}
};
true
};
}
}
if found.is_some() {
debug!("Found {} in {}", pkgid.to_str(), workspace.display());
@ -399,12 +399,12 @@ pub fn uninstall_package_from(workspace: &Path, pkgid: &PkgId) {
let mut did_something = false;
let installed_bin = target_executable_in_workspace(pkgid, workspace);
if installed_bin.exists() {
file::unlink(&installed_bin);
File::unlink(&installed_bin);
did_something = true;
}
let installed_lib = target_library_in_workspace(pkgid, workspace);
if installed_lib.exists() {
file::unlink(&installed_lib);
File::unlink(&installed_lib);
did_something = true;
}
if !did_something {

View File

@ -96,12 +96,11 @@ pub enum CloneResult {
pub fn make_read_only(target: &Path) {
// Now, make all the files in the target dir read-only
do file::walk_dir(target) |p| {
for p in file::walk_dir(target) {
if !p.is_dir() {
assert!(chmod_read_only(p));
};
true
};
assert!(chmod_read_only(&p));
}
}
}
/// Source can be either a URL or a local file path.

View File

@ -14,6 +14,7 @@ use context::{BuildContext, Context, RustcFlags};
use std::{os, run, str, task};
use std::rt::io;
use std::rt::io::file;
use std::rt::io::File;
use extra::arc::Arc;
use extra::arc::RWArc;
use extra::tempfile::TempDir;
@ -83,7 +84,7 @@ fn git_repo_pkg_with_tag(a_tag: ~str) -> PkgId {
}
fn writeFile(file_path: &Path, contents: &str) {
let mut out = file::create(file_path);
let mut out = File::create(file_path);
out.write(contents.as_bytes());
out.write(['\n' as u8]);
}
@ -196,23 +197,13 @@ fn add_git_tag(repo: &Path, tag: ~str) {
}
fn is_rwx(p: &Path) -> bool {
use std::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR};
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
p.stat().perm & io::UserRWX == io::UserRWX
}
fn is_read_only(p: &Path) -> bool {
use std::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR};
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
p.stat().perm & io::UserRWX == io::UserRead
}
fn test_sysroot() -> Path {
@ -398,7 +389,7 @@ fn test_executable_exists(repo: &Path, short_name: &str) -> bool {
fn remove_executable_file(p: &PkgId, workspace: &Path) {
let exec = target_executable_in_workspace(&PkgId::new(p.short_name), workspace);
if exec.exists() {
file::unlink(&exec);
File::unlink(&exec);
}
}
@ -419,7 +410,7 @@ fn built_executable_exists(repo: &Path, short_name: &str) -> bool {
fn remove_built_executable_file(p: &PkgId, workspace: &Path) {
let exec = built_executable_in_workspace(&PkgId::new(p.short_name), workspace);
match exec {
Some(r) => file::unlink(&r),
Some(r) => File::unlink(&r),
None => ()
}
}
@ -553,7 +544,7 @@ fn frob_source_file(workspace: &Path, pkgid: &PkgId, filename: &str) {
do io::io_error::cond.trap(|e| {
cond.raise((p.clone(), format!("Bad path: {}", e.desc)));
}).inside {
let mut w = file::open_stream(p, io::Append, io::Write);
let mut w = File::open_mode(p, io::Append, io::Write);
w.write(bytes!("/* hi */\n"));
}
}
@ -902,7 +893,7 @@ fn package_script_with_default_build() {
let source = Path::new(file!()).dir_path().join_many(
[~"testsuite", ~"pass", ~"src", ~"fancy-lib", ~"pkg.rs"]);
debug!("package_script_with_default_build: {}", source.display());
file::copy(&source, &dir.join_many(["src", "fancy-lib-0.1", "pkg.rs"]));
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!(target_build_dir(dir).join_many([~"fancy-lib", ~"generated.rs"]).exists());
@ -2288,7 +2279,7 @@ fn test_c_dependency_ok() {
debug!("dir = {}", dir.display());
let source = Path::new(file!()).dir_path().join_many(
[~"testsuite", ~"pass", ~"src", ~"c-dependencies", ~"pkg.rs"]);
file::copy(&source, &dir.join_many([~"src", ~"cdep-0.1", ~"pkg.rs"]));
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");
@ -2309,7 +2300,7 @@ fn test_c_dependency_no_rebuilding() {
debug!("dir = {}", dir.display());
let source = Path::new(file!()).dir_path().join_many(
[~"testsuite", ~"pass", ~"src", ~"c-dependencies", ~"pkg.rs"]);
file::copy(&source, &dir.join_many([~"src", ~"cdep-0.1", ~"pkg.rs"]));
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");
@ -2342,7 +2333,7 @@ fn test_c_dependency_yes_rebuilding() {
[~"testsuite", ~"pass", ~"src", ~"c-dependencies", ~"pkg.rs"]);
let target = dir.join_many([~"src", ~"cdep-0.1", ~"pkg.rs"]);
debug!("Copying {} -> {}", source.display(), target.display());
file::copy(&source, &target);
File::copy(&source, &target);
command_line_test([~"build", ~"cdep"], dir);
assert_executable_exists(dir, "cdep");
let out_dir = target_build_dir(dir).join("cdep");
@ -2366,7 +2357,5 @@ fn test_c_dependency_yes_rebuilding() {
/// Returns true if p exists and is executable
fn is_executable(p: &Path) -> bool {
use std::libc::consts::os::posix88::{S_IXUSR};
p.exists() && p.stat().mode & S_IXUSR as u64 == S_IXUSR as u64
p.exists() && p.stat().perm & io::UserExec == io::UserExec
}

View File

@ -12,7 +12,7 @@ extern mod rustpkg;
extern mod rustc;
use std::os;
use std::rt::io::file;
use std::rt::io::File;
use rustpkg::api;
use rustpkg::version::NoVersion;
@ -43,7 +43,7 @@ pub fn main() {
let out_path = os::self_exe_path().expect("Couldn't get self_exe path");
debug!("Writing file");
let mut file = file::create(&out_path.join("generated.rs"));
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());

View File

@ -9,7 +9,7 @@
// except according to those terms.
use std::rt::io;
use std::rt::io::file;
use std::rt::io::File;
use extra::workcache;
use sha1::{Digest, Sha1};
@ -17,7 +17,7 @@ use sha1::{Digest, Sha1};
pub fn digest_file_with_date(path: &Path) -> ~str {
use conditions::bad_path::cond;
match io::result(|| file::open(path).read_to_end()) {
match io::result(|| File::open(path).read_to_end()) {
Ok(bytes) => {
let mut sha = Sha1::new();
sha.input(bytes);

View File

@ -11,10 +11,9 @@
use std::ptr::null;
use std::c_str;
use std::c_str::CString;
use std::libc::c_void;
use std::cast::transmute;
use std::libc;
use std::libc::{c_int};
use std::libc::{c_int, c_char, c_void};
use super::{Request, NativeHandle, Loop, FsCallback, Buf,
status_to_maybe_uv_error, UvError};
@ -49,12 +48,9 @@ impl FsRequest {
assert_eq!(ret, 0);
}
pub fn open_sync(self, loop_: &Loop, path: &CString,
pub fn open_sync(mut self, loop_: &Loop, path: &CString,
flags: int, mode: int) -> Result<c_int, UvError> {
let complete_cb_ptr = {
let mut me = self;
me.req_boilerplate(None)
};
let complete_cb_ptr = self.req_boilerplate(None);
let result = path.with_ref(|p| unsafe {
uvll::fs_open(loop_.native_handle(),
self.native_handle(), p, flags, mode, complete_cb_ptr)
@ -62,11 +58,8 @@ impl FsRequest {
self.sync_cleanup(result)
}
pub fn unlink(self, loop_: &Loop, path: &CString, cb: FsCallback) {
let complete_cb_ptr = {
let mut me = self;
me.req_boilerplate(Some(cb))
};
pub fn unlink(mut self, loop_: &Loop, path: &CString, cb: FsCallback) {
let complete_cb_ptr = self.req_boilerplate(Some(cb));
let ret = path.with_ref(|p| unsafe {
uvll::fs_unlink(loop_.native_handle(),
self.native_handle(), p, complete_cb_ptr)
@ -74,12 +67,9 @@ impl FsRequest {
assert_eq!(ret, 0);
}
pub fn unlink_sync(self, loop_: &Loop, path: &CString)
pub fn unlink_sync(mut self, loop_: &Loop, path: &CString)
-> Result<c_int, UvError> {
let complete_cb_ptr = {
let mut me = self;
me.req_boilerplate(None)
};
let complete_cb_ptr = self.req_boilerplate(None);
let result = path.with_ref(|p| unsafe {
uvll::fs_unlink(loop_.native_handle(),
self.native_handle(), p, complete_cb_ptr)
@ -87,11 +77,17 @@ impl FsRequest {
self.sync_cleanup(result)
}
pub fn stat(self, loop_: &Loop, path: &CString, cb: FsCallback) {
let complete_cb_ptr = {
let mut me = self;
me.req_boilerplate(Some(cb))
};
pub fn lstat(mut self, loop_: &Loop, path: &CString, cb: FsCallback) {
let complete_cb_ptr = self.req_boilerplate(Some(cb));
let ret = path.with_ref(|p| unsafe {
uvll::uv_fs_lstat(loop_.native_handle(),
self.native_handle(), p, complete_cb_ptr)
});
assert_eq!(ret, 0);
}
pub fn stat(mut self, loop_: &Loop, path: &CString, cb: FsCallback) {
let complete_cb_ptr = self.req_boilerplate(Some(cb));
let ret = path.with_ref(|p| unsafe {
uvll::fs_stat(loop_.native_handle(),
self.native_handle(), p, complete_cb_ptr)
@ -99,11 +95,9 @@ impl FsRequest {
assert_eq!(ret, 0);
}
pub fn write(self, loop_: &Loop, fd: c_int, buf: Buf, offset: i64, cb: FsCallback) {
let complete_cb_ptr = {
let mut me = self;
me.req_boilerplate(Some(cb))
};
pub fn write(mut self, loop_: &Loop, fd: c_int, buf: Buf, offset: i64,
cb: FsCallback) {
let complete_cb_ptr = self.req_boilerplate(Some(cb));
let base_ptr = buf.base as *c_void;
let len = buf.len as uint;
let ret = unsafe {
@ -113,12 +107,9 @@ impl FsRequest {
};
assert_eq!(ret, 0);
}
pub fn write_sync(self, loop_: &Loop, fd: c_int, buf: Buf, offset: i64)
pub fn write_sync(mut self, loop_: &Loop, fd: c_int, buf: Buf, offset: i64)
-> Result<c_int, UvError> {
let complete_cb_ptr = {
let mut me = self;
me.req_boilerplate(None)
};
let complete_cb_ptr = self.req_boilerplate(None);
let base_ptr = buf.base as *c_void;
let len = buf.len as uint;
let result = unsafe {
@ -129,11 +120,9 @@ impl FsRequest {
self.sync_cleanup(result)
}
pub fn read(self, loop_: &Loop, fd: c_int, buf: Buf, offset: i64, cb: FsCallback) {
let complete_cb_ptr = {
let mut me = self;
me.req_boilerplate(Some(cb))
};
pub fn read(mut self, loop_: &Loop, fd: c_int, buf: Buf, offset: i64,
cb: FsCallback) {
let complete_cb_ptr = self.req_boilerplate(Some(cb));
let buf_ptr = buf.base as *c_void;
let len = buf.len as uint;
let ret = unsafe {
@ -143,12 +132,9 @@ impl FsRequest {
};
assert_eq!(ret, 0);
}
pub fn read_sync(self, loop_: &Loop, fd: c_int, buf: Buf, offset: i64)
pub fn read_sync(mut self, loop_: &Loop, fd: c_int, buf: Buf, offset: i64)
-> Result<c_int, UvError> {
let complete_cb_ptr = {
let mut me = self;
me.req_boilerplate(None)
};
let complete_cb_ptr = self.req_boilerplate(None);
let buf_ptr = buf.base as *c_void;
let len = buf.len as uint;
let result = unsafe {
@ -159,22 +145,16 @@ impl FsRequest {
self.sync_cleanup(result)
}
pub fn close(self, loop_: &Loop, fd: c_int, cb: FsCallback) {
let complete_cb_ptr = {
let mut me = self;
me.req_boilerplate(Some(cb))
};
let ret = unsafe {
pub fn close(mut self, loop_: &Loop, fd: c_int, cb: FsCallback) {
let complete_cb_ptr = self.req_boilerplate(Some(cb));
assert_eq!(unsafe {
uvll::fs_close(loop_.native_handle(), self.native_handle(),
fd, complete_cb_ptr)
};
assert_eq!(ret, 0);
}, 0);
}
pub fn close_sync(self, loop_: &Loop, fd: c_int) -> Result<c_int, UvError> {
let complete_cb_ptr = {
let mut me = self;
me.req_boilerplate(None)
};
pub fn close_sync(mut self, loop_: &Loop,
fd: c_int) -> Result<c_int, UvError> {
let complete_cb_ptr = self.req_boilerplate(None);
let result = unsafe {
uvll::fs_close(loop_.native_handle(), self.native_handle(),
fd, complete_cb_ptr)
@ -182,68 +162,119 @@ impl FsRequest {
self.sync_cleanup(result)
}
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))
};
let ret = path.with_ref(|p| unsafe {
pub fn mkdir(mut self, loop_: &Loop, path: &CString, mode: c_int,
cb: FsCallback) {
let complete_cb_ptr = self.req_boilerplate(Some(cb));
assert_eq!(path.with_ref(|p| unsafe {
uvll::fs_mkdir(loop_.native_handle(),
self.native_handle(), p, mode, complete_cb_ptr)
});
assert_eq!(ret, 0);
}), 0);
}
pub fn rmdir(self, loop_: &Loop, path: &CString, cb: FsCallback) {
let complete_cb_ptr = {
let mut me = self;
me.req_boilerplate(Some(cb))
};
let ret = path.with_ref(|p| unsafe {
pub fn rmdir(mut self, loop_: &Loop, path: &CString, cb: FsCallback) {
let complete_cb_ptr = self.req_boilerplate(Some(cb));
assert_eq!(path.with_ref(|p| unsafe {
uvll::fs_rmdir(loop_.native_handle(),
self.native_handle(), p, complete_cb_ptr)
});
assert_eq!(ret, 0);
}), 0);
}
pub fn rename(self, loop_: &Loop, path: &CString, to: &CString, cb: FsCallback) {
let complete_cb_ptr = {
let mut me = self;
me.req_boilerplate(Some(cb))
};
let ret = unsafe {
pub fn rename(mut self, loop_: &Loop, path: &CString, to: &CString,
cb: FsCallback) {
let complete_cb_ptr = self.req_boilerplate(Some(cb));
assert_eq!(unsafe {
uvll::fs_rename(loop_.native_handle(),
self.native_handle(),
path.with_ref(|p| p),
to.with_ref(|p| p),
complete_cb_ptr)
};
assert_eq!(ret, 0);
}, 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 {
pub fn chmod(mut self, loop_: &Loop, path: &CString, mode: c_int,
cb: FsCallback) {
let complete_cb_ptr = self.req_boilerplate(Some(cb));
assert_eq!(path.with_ref(|p| unsafe {
uvll::fs_chmod(loop_.native_handle(), self.native_handle(), p, mode,
complete_cb_ptr)
});
assert_eq!(ret, 0);
}), 0);
}
pub fn readdir(self, loop_: &Loop, path: &CString,
pub fn readdir(mut self, loop_: &Loop, path: &CString,
flags: c_int, cb: FsCallback) {
let complete_cb_ptr = {
let mut me = self;
me.req_boilerplate(Some(cb))
};
let ret = path.with_ref(|p| unsafe {
let complete_cb_ptr = self.req_boilerplate(Some(cb));
assert_eq!(path.with_ref(|p| unsafe {
uvll::fs_readdir(loop_.native_handle(),
self.native_handle(), p, flags, complete_cb_ptr)
});
assert_eq!(ret, 0);
}), 0);
}
pub fn readlink(mut self, loop_: &Loop, path: &CString, cb: FsCallback) {
let complete_cb_ptr = self.req_boilerplate(Some(cb));
assert_eq!(path.with_ref(|p| unsafe {
uvll::uv_fs_readlink(loop_.native_handle(),
self.native_handle(), p, complete_cb_ptr)
}), 0);
}
pub fn chown(mut self, loop_: &Loop, path: &CString, uid: int, gid: int,
cb: FsCallback) {
let complete_cb_ptr = self.req_boilerplate(Some(cb));
assert_eq!(path.with_ref(|p| unsafe {
uvll::uv_fs_chown(loop_.native_handle(),
self.native_handle(), p,
uid as uvll::uv_uid_t,
gid as uvll::uv_gid_t,
complete_cb_ptr)
}), 0);
}
pub fn truncate(mut self, loop_: &Loop, file: c_int, offset: i64,
cb: FsCallback) {
let complete_cb_ptr = self.req_boilerplate(Some(cb));
assert_eq!(unsafe {
uvll::uv_fs_ftruncate(loop_.native_handle(),
self.native_handle(), file, offset,
complete_cb_ptr)
}, 0);
}
pub fn link(mut self, loop_: &Loop, src: &CString, dst: &CString,
cb: FsCallback) {
let complete_cb_ptr = self.req_boilerplate(Some(cb));
assert_eq!(unsafe {
uvll::uv_fs_link(loop_.native_handle(), self.native_handle(),
src.with_ref(|p| p),
dst.with_ref(|p| p),
complete_cb_ptr)
}, 0);
}
pub fn symlink(mut self, loop_: &Loop, src: &CString, dst: &CString,
cb: FsCallback) {
let complete_cb_ptr = self.req_boilerplate(Some(cb));
assert_eq!(unsafe {
uvll::uv_fs_symlink(loop_.native_handle(), self.native_handle(),
src.with_ref(|p| p),
dst.with_ref(|p| p),
complete_cb_ptr)
}, 0);
}
pub fn fsync(mut self, loop_: &Loop, fd: c_int, cb: FsCallback) {
let complete_cb_ptr = self.req_boilerplate(Some(cb));
assert_eq!(unsafe {
uvll::uv_fs_fsync(loop_.native_handle(), self.native_handle(), fd,
complete_cb_ptr)
}, 0);
}
pub fn datasync(mut self, loop_: &Loop, fd: c_int, cb: FsCallback) {
let complete_cb_ptr = self.req_boilerplate(Some(cb));
assert_eq!(unsafe {
uvll::uv_fs_fdatasync(loop_.native_handle(), self.native_handle(), fd,
complete_cb_ptr)
}, 0);
}
// accessors/utility funcs
@ -284,10 +315,12 @@ impl FsRequest {
}
}
pub fn get_result(&mut self) -> c_int {
unsafe {
uvll::get_result_from_fs_req(self.native_handle())
}
pub fn get_path(&self) -> *c_char {
unsafe { uvll::get_path_from_fs_req(self.native_handle()) }
}
pub fn get_result(&self) -> c_int {
unsafe { uvll::get_result_from_fs_req(self.native_handle()) }
}
pub fn get_loop(&self) -> Loop {
@ -380,7 +413,7 @@ extern fn compl_cb(req: *uv_fs_t) {
mod test {
use super::*;
//use std::rt::test::*;
use std::libc::{STDOUT_FILENO};
use std::libc::{STDOUT_FILENO, c_int};
use std::vec;
use std::str;
use std::unstable::run_in_bare_thread;

View File

@ -8,18 +8,15 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use std::c_str::{ToCStr, CString};
use std::c_str::CString;
use std::cast::transmute;
use std::cast;
use std::cell::Cell;
use std::clone::Clone;
use std::comm::{SendDeferred, SharedChan, Port, PortOne, GenericChan};
use std::libc;
use std::libc::{c_int, c_uint, c_void, pid_t};
use std::ops::Drop;
use std::option::*;
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};
@ -33,22 +30,16 @@ use std::rt::sched::{Scheduler, SchedHandle};
use std::rt::tube::Tube;
use std::rt::task::Task;
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};
use std::rt::io::{FileMode, FileAccess, OpenOrCreate, Open, Create,
CreateOrTruncate, Append, Truncate, Read, Write, ReadWrite,
FileStat};
use std::libc::{lseek, off_t};
use std::rt::io::{FileMode, FileAccess, FileStat};
use std::rt::io::signal::Signum;
use std::task;
use ai = std::rt::io::net::addrinfo;
#[cfg(test)] use std::container::Container;
#[cfg(test)] use std::unstable::run_in_bare_thread;
#[cfg(test)] use std::rt::test::{spawntask,
next_test_ip4,
run_in_mt_newsched_task};
#[cfg(test)] use std::iter::{Iterator, range};
#[cfg(test)] use std::rt::comm::oneshot;
use super::*;
@ -418,24 +409,25 @@ impl UvIoFactory {
}
}
/// Helper for a variety of simple uv_fs_* functions that
/// have no ret val
fn uv_fs_helper(loop_: &mut Loop, path: &CString,
cb: ~fn(&mut FsRequest, &mut Loop, &CString,
~fn(&FsRequest, Option<UvError>)))
-> Result<(), IoError> {
/// Helper for a variety of simple uv_fs_* functions that have no ret val. This
/// function takes the loop that it will act on, and then invokes the specified
/// callback in a situation where the task wil be immediately blocked
/// afterwards. The `FsCallback` yielded must be invoked to reschedule the task
/// (once the result of the operation is known).
fn uv_fs_helper<T>(loop_: &mut Loop,
retfn: extern "Rust" fn(&mut FsRequest) -> T,
cb: &fn(&mut FsRequest, &mut Loop, FsCallback))
-> Result<T, IoError> {
let result_cell = Cell::new_empty();
let result_cell_ptr: *Cell<Result<(), IoError>> = &result_cell;
let path_cell = Cell::new(path);
let result_cell_ptr: *Cell<Result<T, IoError>> = &result_cell;
do task::unkillable { // FIXME(#8674)
let scheduler: ~Scheduler = Local::take();
let mut new_req = FsRequest::new();
do scheduler.deschedule_running_task_and_then |_, task| {
let task_cell = Cell::new(task);
let path = path_cell.take();
do cb(&mut new_req, loop_, path) |_, err| {
do cb(&mut new_req, loop_) |req, err| {
let res = match err {
None => Ok(()),
None => Ok(retfn(req)),
Some(err) => Err(uv_error_to_io_error(err))
};
unsafe { (*result_cell_ptr).put_back(res); }
@ -448,6 +440,43 @@ fn uv_fs_helper(loop_: &mut Loop, path: &CString,
return result_cell.take();
}
fn unit(_: &mut FsRequest) {}
fn fs_mkstat(f: &mut FsRequest) -> FileStat {
let path = unsafe { Path::new(CString::new(f.get_path(), false)) };
let stat = f.get_stat();
fn to_msec(stat: uvll::uv_timespec_t) -> u64 {
(stat.tv_sec * 1000 + stat.tv_nsec / 1000000) as u64
}
let kind = match (stat.st_mode as c_int) & libc::S_IFMT {
libc::S_IFREG => io::TypeFile,
libc::S_IFDIR => io::TypeDirectory,
libc::S_IFIFO => io::TypeNamedPipe,
libc::S_IFBLK => io::TypeBlockSpecial,
libc::S_IFLNK => io::TypeSymlink,
_ => io::TypeUnknown,
};
FileStat {
path: path,
size: stat.st_size as u64,
kind: kind,
perm: (stat.st_mode as io::FilePermission) & io::AllPermissions,
created: to_msec(stat.st_birthtim),
modified: to_msec(stat.st_mtim),
accessed: to_msec(stat.st_atim),
device: stat.st_dev as u64,
inode: stat.st_ino as u64,
rdev: stat.st_rdev as u64,
nlink: stat.st_nlink as u64,
uid: stat.st_uid as u64,
gid: stat.st_gid as u64,
blksize: stat.st_blksize as u64,
blocks: stat.st_blocks as u64,
flags: stat.st_flags as u64,
gen: stat.st_gen as u64,
}
}
impl IoFactory for UvIoFactory {
// Connect to an address and return a new stream
// NB: This blocks the task waiting on the connection.
@ -552,120 +581,6 @@ impl IoFactory for UvIoFactory {
Ok(~UvTimer::new(watcher, home) as ~RtioTimer)
}
fn fs_from_raw_fd(&mut self, fd: c_int, close: CloseBehavior) -> ~RtioFileStream {
let loop_ = Loop {handle: self.uv_loop().native_handle()};
let home = get_handle_to_current_scheduler!();
~UvFileStream::new(loop_, fd, close, home) as ~RtioFileStream
}
fn fs_open(&mut self, path: &CString, fm: FileMode, fa: FileAccess)
-> Result<~RtioFileStream, IoError> {
let mut flags = match fm {
Open => 0,
Create => O_CREAT,
OpenOrCreate => O_CREAT,
Append => O_APPEND,
Truncate => O_TRUNC,
CreateOrTruncate => O_TRUNC | O_CREAT
};
flags = match fa {
Read => flags | O_RDONLY,
Write => flags | O_WRONLY,
ReadWrite => flags | O_RDWR
};
let create_mode = match fm {
Create|OpenOrCreate|CreateOrTruncate =>
S_IRUSR | S_IWUSR,
_ => 0
};
let result_cell = Cell::new_empty();
let result_cell_ptr: *Cell<Result<~RtioFileStream,
IoError>> = &result_cell;
let path_cell = Cell::new(path);
do task::unkillable { // FIXME(#8674)
let scheduler: ~Scheduler = Local::take();
let open_req = file::FsRequest::new();
do scheduler.deschedule_running_task_and_then |_, task| {
let task_cell = Cell::new(task);
let path = path_cell.take();
do open_req.open(self.uv_loop(), path, flags as int, create_mode as int)
|req,err| {
if err.is_none() {
let loop_ = Loop {handle: req.get_loop().native_handle()};
let home = get_handle_to_current_scheduler!();
let fd = req.get_result() as c_int;
let fs = ~UvFileStream::new(
loop_, fd, CloseSynchronously, home) as ~RtioFileStream;
let res = Ok(fs);
unsafe { (*result_cell_ptr).put_back(res); }
let scheduler: ~Scheduler = Local::take();
scheduler.resume_blocked_task_immediately(task_cell.take());
} else {
let res = Err(uv_error_to_io_error(err.unwrap()));
unsafe { (*result_cell_ptr).put_back(res); }
let scheduler: ~Scheduler = Local::take();
scheduler.resume_blocked_task_immediately(task_cell.take());
}
};
};
};
assert!(!result_cell.is_empty());
return result_cell.take();
}
fn fs_unlink(&mut self, path: &CString) -> Result<(), IoError> {
do uv_fs_helper(self.uv_loop(), path) |unlink_req, l, p, cb| {
do unlink_req.unlink(l, p) |req, err| {
cb(req, err)
};
}
}
fn fs_stat(&mut self, path: &CString) -> Result<FileStat, IoError> {
use str::StrSlice;
let result_cell = Cell::new_empty();
let result_cell_ptr: *Cell<Result<FileStat,
IoError>> = &result_cell;
let path_cell = Cell::new(path);
do task::unkillable { // FIXME(#8674)
let scheduler: ~Scheduler = Local::take();
let stat_req = file::FsRequest::new();
do scheduler.deschedule_running_task_and_then |_, task| {
let task_cell = Cell::new(task);
let path = path_cell.take();
// Don't pick up the null byte
let slice = path.as_bytes().slice(0, path.len());
let path_instance = Cell::new(Path::new(slice));
do stat_req.stat(self.uv_loop(), path) |req,err| {
let res = match err {
None => {
let stat = req.get_stat();
Ok(FileStat {
path: path_instance.take(),
is_file: stat.is_file(),
is_dir: stat.is_dir(),
device: stat.st_dev,
mode: stat.st_mode,
inode: stat.st_ino,
size: stat.st_size,
created: stat.st_ctim.tv_sec as u64,
modified: stat.st_mtim.tv_sec as u64,
accessed: stat.st_atim.tv_sec as u64
})
},
Some(e) => {
Err(uv_error_to_io_error(e))
}
};
unsafe { (*result_cell_ptr).put_back(res); }
let scheduler: ~Scheduler = Local::take();
scheduler.resume_blocked_task_immediately(task_cell.take());
};
};
};
assert!(!result_cell.is_empty());
return result_cell.take();
}
fn get_host_addresses(&mut self, host: Option<&str>, servname: Option<&str>,
hint: Option<ai::Hint>) -> Result<~[ai::Info], IoError> {
let result_cell = Cell::new_empty();
@ -700,39 +615,98 @@ impl IoFactory for UvIoFactory {
assert!(!result_cell.is_empty());
return result_cell.take();
}
fn fs_from_raw_fd(&mut self, fd: c_int, close: CloseBehavior) -> ~RtioFileStream {
let loop_ = Loop {handle: self.uv_loop().native_handle()};
let home = get_handle_to_current_scheduler!();
~UvFileStream::new(loop_, fd, close, home) as ~RtioFileStream
}
fn fs_open(&mut self, path: &CString, fm: FileMode, fa: FileAccess)
-> Result<~RtioFileStream, IoError> {
let flags = match fm {
io::Open => 0,
io::Append => libc::O_APPEND,
io::Truncate => libc::O_TRUNC,
};
// Opening with a write permission must silently create the file.
let (flags, mode) = match fa {
io::Read => (flags | libc::O_RDONLY, 0),
io::Write => (flags | libc::O_WRONLY | libc::O_CREAT,
libc::S_IRUSR | libc::S_IWUSR),
io::ReadWrite => (flags | libc::O_RDWR | libc::O_CREAT,
libc::S_IRUSR | libc::S_IWUSR),
};
let result_cell = Cell::new_empty();
let result_cell_ptr: *Cell<Result<~RtioFileStream,
IoError>> = &result_cell;
do task::unkillable { // FIXME(#8674)
let scheduler: ~Scheduler = Local::take();
let open_req = file::FsRequest::new();
do scheduler.deschedule_running_task_and_then |_, task| {
let task_cell = Cell::new(task);
do open_req.open(self.uv_loop(), path, flags as int, mode as int)
|req,err| {
if err.is_none() {
let loop_ = Loop {handle: req.get_loop().native_handle()};
let home = get_handle_to_current_scheduler!();
let fd = req.get_result() as c_int;
let fs = ~UvFileStream::new(
loop_, fd, CloseSynchronously, home) as ~RtioFileStream;
let res = Ok(fs);
unsafe { (*result_cell_ptr).put_back(res); }
let scheduler: ~Scheduler = Local::take();
scheduler.resume_blocked_task_immediately(task_cell.take());
} else {
let res = Err(uv_error_to_io_error(err.unwrap()));
unsafe { (*result_cell_ptr).put_back(res); }
let scheduler: ~Scheduler = Local::take();
scheduler.resume_blocked_task_immediately(task_cell.take());
}
};
};
};
assert!(!result_cell.is_empty());
return result_cell.take();
}
fn fs_unlink(&mut self, path: &CString) -> Result<(), IoError> {
do uv_fs_helper(self.uv_loop(), unit) |req, l, cb| {
req.unlink(l, path, cb)
}
}
fn fs_lstat(&mut self, path: &CString) -> Result<FileStat, IoError> {
do uv_fs_helper(self.uv_loop(), fs_mkstat) |req, l, cb| {
req.lstat(l, path, cb)
}
}
fn fs_stat(&mut self, path: &CString) -> Result<FileStat, IoError> {
do uv_fs_helper(self.uv_loop(), fs_mkstat) |req, l, cb| {
req.stat(l, path, cb)
}
}
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, perm as c_int) |req, err| {
cb(req, err)
};
do uv_fs_helper(self.uv_loop(), unit) |req, l, cb| {
req.mkdir(l, path, perm as c_int, cb)
}
}
fn fs_rmdir(&mut self, path: &CString) -> Result<(), IoError> {
do uv_fs_helper(self.uv_loop(), path) |rmdir_req, l, p, cb| {
do rmdir_req.rmdir(l, p) |req, err| {
cb(req, err)
};
do uv_fs_helper(self.uv_loop(), unit) |req, l, cb| {
req.rmdir(l, path, cb)
}
}
fn fs_rename(&mut self, path: &CString, to: &CString) -> Result<(), IoError> {
let to = to.with_ref(|p| p);
do uv_fs_helper(self.uv_loop(), path) |rename_req, l, p, cb| {
let to = unsafe { CString::new(to, false) };
do rename_req.rename(l, p, &to) |req, err| {
cb(req, err)
};
do uv_fs_helper(self.uv_loop(), unit) |req, l, cb| {
req.rename(l, path, to, cb)
}
}
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)
};
do uv_fs_helper(self.uv_loop(), unit) |req, l, cb| {
req.chmod(l, path, perm as c_int, cb)
}
}
>>>>>>> Remove all blocking std::os blocking functions
fn fs_readdir(&mut self, path: &CString, flags: c_int) ->
Result<~[Path], IoError> {
use str::StrSlice;
@ -773,6 +747,29 @@ impl IoFactory for UvIoFactory {
assert!(!result_cell.is_empty());
return result_cell.take();
}
fn fs_link(&mut self, src: &CString, dst: &CString) -> Result<(), IoError> {
do uv_fs_helper(self.uv_loop(), unit) |req, l, cb| {
req.link(l, src, dst, cb)
}
}
fn fs_symlink(&mut self, src: &CString, dst: &CString) -> Result<(), IoError> {
do uv_fs_helper(self.uv_loop(), unit) |req, l, cb| {
req.symlink(l, src, dst, cb)
}
}
fn fs_chown(&mut self, path: &CString, uid: int, gid: int) -> Result<(), IoError> {
do uv_fs_helper(self.uv_loop(), unit) |req, l, cb| {
req.chown(l, path, uid, gid, cb)
}
}
fn fs_readlink(&mut self, path: &CString) -> Result<Path, IoError> {
fn getlink(f: &mut FsRequest) -> Path {
Path::new(unsafe { CString::new(f.get_path(), false) })
}
do uv_fs_helper(self.uv_loop(), getlink) |req, l, cb| {
req.readlink(l, path, cb)
}
}
fn spawn(&mut self, config: ProcessConfig)
-> Result<(~RtioProcess, ~[Option<~RtioPipe>]), IoError>
@ -1581,26 +1578,9 @@ impl UvFileStream {
result_cell.take()
}
fn base_write(&mut self, buf: &[u8], offset: i64) -> Result<(), IoError> {
let result_cell = Cell::new_empty();
let result_cell_ptr: *Cell<Result<(), IoError>> = &result_cell;
let buf_ptr: *&[u8] = &buf;
do self.home_for_io_with_sched |self_, scheduler| {
do scheduler.deschedule_running_task_and_then |_, task| {
let buf = unsafe { slice_to_uv_buf(*buf_ptr) };
let task_cell = Cell::new(task);
let write_req = file::FsRequest::new();
do write_req.write(&self_.loop_, self_.fd, buf, offset) |_, uverr| {
let res = match uverr {
None => Ok(()),
Some(err) => Err(uv_error_to_io_error(err))
};
unsafe { (*result_cell_ptr).put_back(res); }
let scheduler: ~Scheduler = Local::take();
scheduler.resume_blocked_task_immediately(task_cell.take());
}
}
do self.nop_req |self_, req, cb| {
req.write(&self_.loop_, self_.fd, slice_to_uv_buf(buf), offset, cb)
}
result_cell.take()
}
fn seek_common(&mut self, pos: i64, whence: c_int) ->
Result<u64, IoError>{
@ -1618,6 +1598,27 @@ impl UvFileStream {
}
}
}
fn nop_req(&mut self, f: &fn(&mut UvFileStream, file::FsRequest, FsCallback))
-> Result<(), IoError> {
let result_cell = Cell::new_empty();
let result_cell_ptr: *Cell<Result<(), IoError>> = &result_cell;
do self.home_for_io_with_sched |self_, sched| {
do sched.deschedule_running_task_and_then |_, task| {
let task = Cell::new(task);
let req = file::FsRequest::new();
do f(self_, req) |_, uverr| {
let res = match uverr {
None => Ok(()),
Some(err) => Err(uv_error_to_io_error(err))
};
unsafe { (*result_cell_ptr).put_back(res); }
let scheduler: ~Scheduler = Local::take();
scheduler.resume_blocked_task_immediately(task.take());
}
}
}
result_cell.take()
}
}
impl Drop for UvFileStream {
@ -1672,6 +1673,21 @@ impl RtioFileStream for UvFileStream {
let self_ = unsafe { cast::transmute::<&UvFileStream, &mut UvFileStream>(self) };
self_.seek_common(0, SEEK_CUR)
}
fn fsync(&mut self) -> Result<(), IoError> {
do self.nop_req |self_, req, cb| {
req.fsync(&self_.loop_, self_.fd, cb)
}
}
fn datasync(&mut self) -> Result<(), IoError> {
do self.nop_req |self_, req, cb| {
req.datasync(&self_.loop_, self_.fd, cb)
}
}
fn truncate(&mut self, offset: i64) -> Result<(), IoError> {
do self.nop_req |self_, req, cb| {
req.truncate(&self_.loop_, self_.fd, offset, cb)
}
}
}
pub struct UvProcess {
@ -2489,13 +2505,13 @@ fn test_timer_sleep_simple() {
}
fn file_test_uvio_full_simple_impl() {
use std::rt::io::{Open, Create, ReadWrite, Read};
use std::rt::io::{Open, ReadWrite, Read};
unsafe {
let io = local_io();
let write_val = "hello uvio!";
let path = "./tmp/file_test_uvio_full.txt";
{
let create_fm = Create;
let create_fm = Open;
let create_fa = ReadWrite;
let mut fd = io.fs_open(&path.to_c_str(), create_fm, create_fa).unwrap();
let write_buf = write_val.as_bytes();

View File

@ -222,6 +222,7 @@ pub type uv_exit_cb = extern "C" fn(handle: *uv_process_t,
term_signal: c_int);
pub type uv_signal_cb = extern "C" fn(handle: *uv_signal_t,
signum: c_int);
pub type uv_fs_cb = extern "C" fn(req: *uv_fs_t);
pub type sockaddr = c_void;
pub type sockaddr_in = c_void;
@ -886,6 +887,11 @@ pub unsafe fn get_ptr_from_fs_req(req: *uv_fs_t) -> *libc::c_void {
rust_uv_get_ptr_from_fs_req(req)
}
pub unsafe fn get_path_from_fs_req(req: *uv_fs_t) -> *c_char {
#[fixed_stack_segment]; #[inline(never)];
rust_uv_get_path_from_fs_req(req)
}
pub unsafe fn get_loop_from_fs_req(req: *uv_fs_t) -> *uv_loop_t {
#[fixed_stack_segment]; #[inline(never)];
@ -1129,6 +1135,7 @@ extern {
fn rust_uv_populate_uv_stat(req_in: *uv_fs_t, stat_out: *uv_stat_t);
fn rust_uv_get_result_from_fs_req(req: *uv_fs_t) -> c_int;
fn rust_uv_get_ptr_from_fs_req(req: *uv_fs_t) -> *libc::c_void;
fn rust_uv_get_path_from_fs_req(req: *uv_fs_t) -> *c_char;
fn rust_uv_get_loop_from_fs_req(req: *uv_fs_t) -> *uv_loop_t;
fn rust_uv_get_loop_from_getaddrinfo_req(req: *uv_fs_t) -> *uv_loop_t;
@ -1189,7 +1196,24 @@ extern {
signal_cb: uv_signal_cb,
signum: c_int) -> c_int;
fn rust_uv_signal_stop(handle: *uv_signal_t) -> c_int;
}
externfn!(fn uv_fs_fsync(handle: *uv_loop_t, req: *uv_fs_t, file: c_int,
cb: *u8) -> c_int)
externfn!(fn uv_fs_fdatasync(handle: *uv_loop_t, req: *uv_fs_t, file: c_int,
cb: *u8) -> c_int)
externfn!(fn uv_fs_ftruncate(handle: *uv_loop_t, req: *uv_fs_t, file: c_int,
offset: i64, cb: *u8) -> c_int)
externfn!(fn uv_fs_readlink(handle: *uv_loop_t, req: *uv_fs_t, file: *c_char,
cb: *u8) -> c_int)
externfn!(fn uv_fs_symlink(handle: *uv_loop_t, req: *uv_fs_t, src: *c_char,
dst: *c_char, cb: *u8) -> c_int)
externfn!(fn uv_fs_link(handle: *uv_loop_t, req: *uv_fs_t, src: *c_char,
dst: *c_char, cb: *u8) -> c_int)
externfn!(fn uv_fs_chown(handle: *uv_loop_t, req: *uv_fs_t, src: *c_char,
uid: uv_uid_t, gid: uv_gid_t, cb: *u8) -> c_int)
externfn!(fn uv_fs_lstat(handle: *uv_loop_t, req: *uv_fs_t, file: *c_char,
cb: *u8) -> c_int)
// libuv requires various system libraries to successfully link on some
// platforms

View File

@ -142,7 +142,7 @@ pub use libc::consts::os::c95::{SEEK_SET, TMP_MAX};
pub use libc::consts::os::posix88::{F_OK, O_APPEND, O_CREAT, O_EXCL};
pub use libc::consts::os::posix88::{O_RDONLY, O_RDWR, O_TRUNC, O_WRONLY};
pub use libc::consts::os::posix88::{R_OK, S_IEXEC, S_IFBLK, S_IFCHR};
pub use libc::consts::os::posix88::{S_IFDIR, S_IFIFO, S_IFMT, S_IFREG};
pub use libc::consts::os::posix88::{S_IFDIR, S_IFIFO, S_IFMT, S_IFREG, S_IFLNK};
pub use libc::consts::os::posix88::{S_IREAD, S_IRUSR, S_IRWXU, S_IWUSR};
pub use libc::consts::os::posix88::{STDERR_FILENO, STDIN_FILENO};
pub use libc::consts::os::posix88::{STDOUT_FILENO, W_OK, X_OK};
@ -1168,6 +1168,7 @@ pub mod consts {
pub static S_IFBLK : c_int = 12288;
pub static S_IFDIR : c_int = 16384;
pub static S_IFREG : c_int = 32768;
pub static S_IFLNK : c_int = 40960;
pub static S_IFMT : c_int = 61440;
pub static S_IEXEC : c_int = 64;
pub static S_IWRITE : c_int = 128;
@ -1345,6 +1346,7 @@ pub mod consts {
pub static S_IFBLK : c_int = 24576;
pub static S_IFDIR : c_int = 16384;
pub static S_IFREG : c_int = 32768;
pub static S_IFLNK : c_int = 40960;
pub static S_IFMT : c_int = 61440;
pub static S_IEXEC : c_int = 64;
pub static S_IWRITE : c_int = 128;
@ -1555,6 +1557,7 @@ pub mod consts {
pub static S_IFBLK : c_int = 24576;
pub static S_IFDIR : c_int = 16384;
pub static S_IFREG : c_int = 32768;
pub static S_IFLNK : c_int = 40960;
pub static S_IFMT : c_int = 61440;
pub static S_IEXEC : c_int = 64;
pub static S_IWRITE : c_int = 128;
@ -1999,6 +2002,7 @@ pub mod consts {
pub static S_IFBLK : c_int = 24576;
pub static S_IFDIR : c_int = 16384;
pub static S_IFREG : c_int = 32768;
pub static S_IFLNK : c_int = 40960;
pub static S_IFMT : c_int = 61440;
pub static S_IEXEC : c_int = 64;
pub static S_IWRITE : c_int = 128;
@ -2341,6 +2345,7 @@ pub mod consts {
pub static S_IFBLK : c_int = 24576;
pub static S_IFDIR : c_int = 16384;
pub static S_IFREG : c_int = 32768;
pub static S_IFLNK : c_int = 40960;
pub static S_IFMT : c_int = 61440;
pub static S_IEXEC : c_int = 64;
pub static S_IWRITE : c_int = 128;

View File

@ -1495,7 +1495,7 @@ mod tests {
use result::{Ok, Err};
use os::*;
use libc::*;
use rt::io::file;
use rt::io::File;
#[cfg(unix)]
#[fixed_stack_segment]
@ -1544,7 +1544,7 @@ mod tests {
assert!(*chunk.data == 0xbe);
close(fd);
}
file::unlink(&path);
File::unlink(&path);
}
// More recursive_mkdir tests are in extra::tempfile

View File

@ -23,9 +23,6 @@ use to_bytes::IterBytes;
use vec::Vector;
use super::{contains_nul, BytesContainer, GenericPath, GenericPathUnsafe};
#[cfg(target_os = "win32")]
use rt::io::{FileStat, file, io_error};
/// Iterator that yields successive components of a Path as &str
///
/// Each component is yielded as Option<&str> for compatibility with PosixPath, but
@ -1056,67 +1053,6 @@ fn prefix_is_sep(p: Option<PathPrefix>, c: u8) -> bool {
else { is_sep_verbatim(c as char) }
}
// Stat support
#[cfg(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)
}
}
/// 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::*;

View File

@ -13,12 +13,11 @@
use rand::Rng;
use ops::Drop;
use path::Path;
#[cfg(unix)]
use rand::reader::ReaderRng;
#[cfg(unix)]
use rt::io::file;
use rt::io::File;
#[cfg(windows)]
use cast;
@ -41,7 +40,7 @@ type HCRYPTPROV = c_long;
/// This does not block.
#[cfg(unix)]
pub struct OSRng {
priv inner: ReaderRng<file::FileReader>
priv inner: ReaderRng<File>
}
/// A random number generator that retrieves randomness straight from
/// the operating system. Platform sources:
@ -61,7 +60,8 @@ impl OSRng {
/// Create a new `OSRng`.
#[cfg(unix)]
pub fn new() -> OSRng {
let reader = file::open(&Path::new("/dev/urandom"));
use path::Path;
let reader = File::open(&Path::new("/dev/urandom"));
let reader = reader.expect("Error opening /dev/urandom");
let reader_rng = ReaderRng::new(reader);

File diff suppressed because it is too large Load Diff

View File

@ -231,8 +231,6 @@ Out of scope
* Trait for things that are both readers and writers, Stream?
* How to handle newline conversion
* String conversion
* File vs. FileStream? File is shorter but could also be used for getting file info
- maybe File is for general file querying and *also* has a static `open` method
* open vs. connect for generic stream opening
* Do we need `close` at all? dtors might be good enough
* How does I/O relate to the Iterator trait?
@ -244,7 +242,6 @@ Out of scope
use cast;
use int;
use libc;
use path::Path;
use str::{StrSlice, OwnedStr};
use option::{Option, Some, None};
@ -262,7 +259,7 @@ pub use self::stdio::stderr;
pub use self::stdio::print;
pub use self::stdio::println;
pub use self::file::FileStream;
pub use self::file::File;
pub use self::timer::Timer;
pub use self::net::ip::IpAddr;
pub use self::net::tcp::TcpListener;
@ -465,7 +462,7 @@ pub trait Reader {
///
/// # Example
///
/// let reader = FileStream::new()
/// let reader = File::open(&Path::new("foo.txt"))
/// while !reader.eof() {
/// println(reader.read_line());
/// }
@ -1104,55 +1101,103 @@ pub fn placeholder_error() -> IoError {
}
}
/// Instructions on how to open a file and return a `FileStream`.
/// A mode specifies how a file should be opened or created. These modes are
/// passed to `File::open_mode` and are used to control where the file is
/// positioned when it is initially opened.
pub enum FileMode {
/// Opens an existing file. IoError if file does not exist.
/// Opens a file positioned at the beginning.
Open,
/// Creates a file. IoError if file exists.
Create,
/// Opens an existing file or creates a new one.
OpenOrCreate,
/// Opens an existing file or creates a new one, positioned at EOF.
/// Opens a file positioned at EOF.
Append,
/// Opens an existing file, truncating it to 0 bytes.
/// Opens a file, truncating it if it already exists.
Truncate,
/// Opens an existing file or creates a new one, truncating it to 0 bytes.
CreateOrTruncate,
}
/// Access permissions with which the file should be opened.
/// `FileStream`s opened with `Read` will raise an `io_error` condition if written to.
/// Access permissions with which the file should be opened. `File`s
/// opened with `Read` will raise an `io_error` condition if written to.
pub enum FileAccess {
Read,
Write,
ReadWrite
ReadWrite,
}
/// Different kinds of files which can be identified by a call to stat
#[deriving(Eq)]
pub enum FileType {
TypeFile,
TypeDirectory,
TypeNamedPipe,
TypeBlockSpecial,
TypeSymlink,
TypeUnknown,
}
pub struct FileStat {
/// A `Path` object containing information about the `PathInfo`'s location
/// The path that this stat structure is describing
path: Path,
/// `true` if the file pointed at by the `PathInfo` is a regular file
is_file: bool,
/// `true` if the file pointed at by the `PathInfo` is a directory
is_dir: bool,
/// The file pointed at by the `PathInfo`'s device
device: u64,
/// The file pointed at by the `PathInfo`'s mode
mode: u64,
/// The file pointed at by the `PathInfo`'s inode
inode: u64,
/// The file pointed at by the `PathInfo`'s size in bytes
/// The size of the file, in bytes
size: u64,
/// The file pointed at by the `PathInfo`'s creation time
/// The kind of file this path points to (directory, file, pipe, etc.)
kind: FileType,
/// The file permissions currently on the file
perm: FilePermission,
// XXX: These time fields are pretty useless without an actual time
// representation, what are the milliseconds relative to?
/// The time that the file was created at, in platform-dependent
/// milliseconds
created: u64,
/// The file pointed at by the `PathInfo`'s last-modification time in
/// platform-dependent msecs
/// The time that this file was last modified, in platform-dependent
/// milliseconds
modified: u64,
/// The file pointed at by the `PathInfo`'s last-accessd time (e.g. read) in
/// platform-dependent msecs
/// The time that this file was last accessed, in platform-dependent
/// milliseconds
accessed: u64,
// Various filesytem info
device: u64,
inode: u64,
rdev: u64,
nlink: u64,
uid: u64,
gid: u64,
blksize: u64,
blocks: u64,
flags: u64,
gen: u64,
}
// FIXME(#10131): this needs to get designed for real
/// A set of permissions for a file or directory is represented by a set of
/// flags which are or'd together.
pub type FilePermission = u32;
pub static UserRWX: FilePermission = libc::S_IRWXU as FilePermission;
// Each permission bit
pub static UserRead: FilePermission = 0x100;
pub static UserWrite: FilePermission = 0x080;
pub static UserExecute: FilePermission = 0x040;
pub static GroupRead: FilePermission = 0x020;
pub static GroupWrite: FilePermission = 0x010;
pub static GroupExecute: FilePermission = 0x008;
pub static OtherRead: FilePermission = 0x004;
pub static OtherWrite: FilePermission = 0x002;
pub static OtherExecute: FilePermission = 0x001;
// Common combinations of these bits
pub static UserRWX: FilePermission = UserRead | UserWrite | UserExecute;
pub static GroupRWX: FilePermission = GroupRead | GroupWrite | GroupExecute;
pub static OtherRWX: FilePermission = OtherRead | OtherWrite | OtherExecute;
/// A set of permissions for user owned files, this is equivalent to 0644 on
/// unix-like systems.
pub static UserFile: FilePermission = UserRead | UserWrite | GroupRead | OtherRead;
/// A set of permissions for user owned directories, this is equivalent to 0755
/// on unix-like systems.
pub static UserDir: FilePermission = UserRWX | GroupRead | GroupExecute |
OtherRead | OtherExecute;
/// A set of permissions for user owned executables, this is equivalent to 0755
/// on unix-like systems.
pub static UserExec: FilePermission = UserDir;
/// A mask for all possible permission bits
pub static AllPermissions: FilePermission = 0x1ff;

View File

@ -309,14 +309,16 @@ mod tests {
// 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(not(windows))] use c_str::CString;
#[cfg(not(windows))] use libc::fclose;
#[cfg(test)] #[cfg(windows)] use os;
#[cfg(test)] use rand;
#[cfg(windows)] use str;
#[cfg(windows)] use ptr;
// On Windows, wide character version of function must be used to support
// unicode, so functions should be split into at least two versions,
@ -651,7 +653,7 @@ mod old_os {
return false;
}
// Preserve permissions
let from_mode = from.stat().mode;
let from_mode = from.stat().perm;
let ostream = do to.with_c_str |top| {
do "w+b".with_c_str |modebuf| {
@ -735,8 +737,8 @@ mod old_os {
#[test]
fn test_path_is_dir() {
use rt::io::file::{open_stream, mkdir_recursive};
use rt::io::{OpenOrCreate, Read, UserRWX};
use rt::io::file::{mkdir_recursive};
use rt::io::{File, UserRWX};
assert!((path_is_dir(&Path::new("."))));
assert!((!path_is_dir(&Path::new("test/stdtest/fs.rs"))));
@ -754,7 +756,7 @@ mod old_os {
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
File::create(&filepath); // ignore return; touch only
assert!((!path_is_dir(&filepath)));
assert!((!path_is_dir(&Path::new(

View File

@ -11,7 +11,7 @@
//! Implementations of I/O traits for the Option type
//!
//! I/O constructors return option types to allow errors to be handled.
//! These implementations allow e.g. `Option<FileStream>` to be used
//! These implementations allow e.g. `Option<File>` to be used
//! as a `Reader` without unwrapping the option first.
use option::*;

View File

@ -91,12 +91,17 @@ pub fn with_local_io<T>(f: &fn(&mut IoFactory) -> Option<T>) -> Option<T> {
}
pub trait IoFactory {
// networking
fn tcp_connect(&mut self, addr: SocketAddr) -> Result<~RtioTcpStream, IoError>;
fn tcp_bind(&mut self, addr: SocketAddr) -> Result<~RtioTcpListener, IoError>;
fn udp_bind(&mut self, addr: SocketAddr) -> Result<~RtioUdpSocket, IoError>;
fn unix_bind(&mut self, path: &CString) ->
Result<~RtioUnixListener, IoError>;
fn unix_connect(&mut self, path: &CString) -> Result<~RtioPipe, IoError>;
fn get_host_addresses(&mut self, host: Option<&str>, servname: Option<&str>,
hint: Option<ai::Hint>) -> Result<~[ai::Info], IoError>;
fn timer_init(&mut self) -> Result<~RtioTimer, IoError>;
// filesystem operations
fn fs_from_raw_fd(&mut self, fd: c_int, close: CloseBehavior) -> ~RtioFileStream;
fn fs_open(&mut self, path: &CString, fm: FileMode, fa: FileAccess)
-> Result<~RtioFileStream, IoError>;
@ -110,13 +115,18 @@ pub trait IoFactory {
fn fs_rename(&mut self, path: &CString, to: &CString) -> Result<(), IoError>;
fn fs_readdir(&mut self, path: &CString, flags: c_int) ->
Result<~[Path], IoError>;
fn fs_lstat(&mut self, path: &CString) -> Result<FileStat, IoError>;
fn fs_chown(&mut self, path: &CString, uid: int, gid: int) ->
Result<(), IoError>;
fn fs_readlink(&mut self, path: &CString) -> Result<Path, IoError>;
fn fs_symlink(&mut self, src: &CString, dst: &CString) -> Result<(), IoError>;
fn fs_link(&mut self, src: &CString, dst: &CString) -> Result<(), IoError>;
// misc
fn timer_init(&mut self) -> Result<~RtioTimer, IoError>;
fn spawn(&mut self, config: ProcessConfig)
-> Result<(~RtioProcess, ~[Option<~RtioPipe>]), IoError>;
fn pipe_open(&mut self, fd: c_int) -> Result<~RtioPipe, IoError>;
fn unix_bind(&mut self, path: &CString) ->
Result<~RtioUnixListener, IoError>;
fn unix_connect(&mut self, path: &CString) -> Result<~RtioPipe, IoError>;
fn tty_open(&mut self, fd: c_int, readable: bool)
-> Result<~RtioTTY, IoError>;
fn signal(&mut self, signal: Signum, channel: SharedChan<Signum>)
@ -177,6 +187,9 @@ pub trait RtioFileStream {
fn pwrite(&mut self, buf: &[u8], offset: u64) -> Result<(), IoError>;
fn seek(&mut self, pos: i64, whence: SeekStyle) -> Result<u64, IoError>;
fn tell(&self) -> Result<u64, IoError>;
fn fsync(&mut self) -> Result<(), IoError>;
fn datasync(&mut self) -> Result<(), IoError>;
fn truncate(&mut self, offset: i64) -> Result<(), IoError>;
}
pub trait RtioProcess {

View File

@ -20,8 +20,7 @@ use parse::token::{get_ident_interner};
use print::pprust;
use std::rt::io;
use std::rt::io::Reader;
use std::rt::io::file;
use std::rt::io::File;
use std::str;
// These macros all relate to the file system; they either return
@ -92,7 +91,7 @@ pub fn expand_include_str(cx: @ExtCtxt, sp: Span, tts: &[ast::token_tree])
-> 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 bytes = match io::result(|| file::open(&file).read_to_end()) {
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));
@ -114,7 +113,7 @@ pub fn expand_include_bin(cx: @ExtCtxt, sp: Span, tts: &[ast::token_tree])
let file = get_single_str_from_tts(cx, sp, tts, "include_bin!");
let file = res_rel_file(cx, sp, &Path::new(file));
match io::result(|| file::open(&file).read_to_end()) {
match io::result(|| File::open(&file).read_to_end()) {
Err(e) => {
cx.span_fatal(sp, format!("couldn't read {}: {}",
file.display(), e.desc));

View File

@ -19,9 +19,8 @@ use parse::attr::parser_attr;
use parse::lexer::reader;
use parse::parser::Parser;
use std::path::Path;
use std::rt::io;
use std::rt::io::file;
use std::rt::io::File;
use std::str;
pub mod lexer;
@ -268,7 +267,7 @@ pub fn file_to_filemap(sess: @mut ParseSess, path: &Path, spanopt: Option<Span>)
None => sess.span_diagnostic.handler().fatal(msg),
}
};
let bytes = match io::result(|| file::open(path).read_to_end()) {
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));

View File

@ -532,6 +532,10 @@ extern "C" int
rust_uv_get_result_from_fs_req(uv_fs_t* req) {
return req->result;
}
extern "C" const char*
rust_uv_get_path_from_fs_req(uv_fs_t* req) {
return req->path;
}
extern "C" void*
rust_uv_get_ptr_from_fs_req(uv_fs_t* req) {
return req->ptr;

View File

@ -21,7 +21,7 @@ use std::rand;
use std::str;
use std::util;
use std::vec;
use std::rt::io::file;
use std::rt::io::File;
macro_rules! bench (
($argv:expr, $id:ident) => (maybe_run_test($argv, stringify!($id).to_owned(), $id))
@ -76,7 +76,7 @@ fn read_line() {
path.push("src/test/bench/shootout-k-nucleotide.data");
for _ in range(0, 3) {
let mut reader = BufferedReader::new(file::open(&path).unwrap());
let mut reader = BufferedReader::new(File::open(&path).unwrap());
while !reader.eof() {
reader.read_line();
}

View File

@ -19,7 +19,7 @@ extern mod extra;
use std::int;
use std::rt::io;
use std::rt::io::file;
use std::rt::io::File;
use std::os;
use std::rand::Rng;
use std::rand;
@ -123,7 +123,7 @@ fn main() {
};
let writer = if os::getenv("RUST_BENCH").is_some() {
let file = file::create(&Path::new("./shootout-fasta.data"));
let file = File::create(&Path::new("./shootout-fasta.data"));
@mut file as @mut io::Writer
} else {
@mut io::stdout() as @mut io::Writer

View File

@ -23,7 +23,7 @@ pub fn main() {
if directory {
io::file::mkdir(&Path::new(path), io::UserRWX);
} else {
io::file::create(&Path::new(path));
io::File::create(&Path::new(path));
}
}

View File

@ -19,6 +19,7 @@ use std::os;
use std::libc;
use std::rt::io;
use std::rt::io::file;
use std::rt::io::File;
fn rename_directory() {
#[fixed_stack_segment];
@ -50,7 +51,7 @@ fn rename_directory() {
let new_path = tmpdir.join_many(["quux", "blat"]);
file::mkdir_recursive(&new_path, io::UserRWX);
file::rename(&old_path, &new_path.join("newdir"));
File::rename(&old_path, &new_path.join("newdir"));
assert!(new_path.join("newdir").is_dir());
assert!(new_path.join_many(["newdir", "temp.txt"]).exists());
}

View File

@ -13,14 +13,14 @@
extern mod extra;
use extra::tempfile;
use std::rt::io::file;
use std::rt::io::File;
pub fn main() {
let dir = tempfile::TempDir::new_in(&Path::new("."), "").unwrap();
let path = dir.path().join("file");
{
match file::create(&path) {
match File::create(&path) {
None => unreachable!(),
Some(f) => {
let mut f = f;