auto merge of #10495 : alexcrichton/rust/more-native-io, r=brson
This implements a fair amount of the unimpl() functionality in io::native relating to filesystem operations. I've also modified all io::fs tests to run in both a native and uv environment (so everything is actually tested). There are a few bits of remaining functionality which I was unable to get working: * truncate on windows * change_file_times on windows * lstat on windows I think that change_file_times may just need a better interface, but the other two have large implementations in libuv which I didn't want to tackle trying to copy. I found a `chsize` function to work for truncate on windows, but it doesn't quite seem to be working out.
This commit is contained in:
commit
eef913b290
@ -391,7 +391,6 @@ mod test {
|
||||
// newtype struct autoderef weirdness
|
||||
#[test]
|
||||
fn test_buffered_stream() {
|
||||
use rt;
|
||||
struct S;
|
||||
|
||||
impl io::Writer for S {
|
||||
|
@ -191,7 +191,7 @@ impl File {
|
||||
///
|
||||
/// This function will raise on the `io_error` condition on failure.
|
||||
pub fn fsync(&mut self) {
|
||||
self.fd.fsync();
|
||||
self.fd.fsync().map_err(|e| io_error::cond.raise(e));
|
||||
}
|
||||
|
||||
/// This function is similar to `fsync`, except that it may not synchronize
|
||||
@ -203,23 +203,23 @@ impl File {
|
||||
///
|
||||
/// This function will raise on the `io_error` condition on failure.
|
||||
pub fn datasync(&mut self) {
|
||||
self.fd.datasync();
|
||||
self.fd.datasync().map_err(|e| io_error::cond.raise(e));
|
||||
}
|
||||
|
||||
/// Either truncates or extends the underlying file, as extended from the
|
||||
/// file's current position. This is equivalent to the unix `truncate`
|
||||
/// Either truncates or extends the underlying file, updating the size of
|
||||
/// this file to become `size`. This is equivalent to unix's `truncate`
|
||||
/// function.
|
||||
///
|
||||
/// The offset given is added to the file's current position and the result
|
||||
/// is the new size of the file. If the new size is less than the current
|
||||
/// size, then the file is truncated. If the new size is greater than the
|
||||
/// current size, then the file is expanded to be filled with 0s.
|
||||
/// If the `size` is less than the current file's size, then the file will
|
||||
/// be shrunk. If it is greater than the current file's size, then the file
|
||||
/// will be extended to `size` and have all of the intermediate data filled
|
||||
/// in with 0s.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// On error, this function will raise on the `io_error` condition.
|
||||
pub fn truncate(&mut self, offset: i64) {
|
||||
self.fd.truncate(offset);
|
||||
pub fn truncate(&mut self, size: i64) {
|
||||
self.fd.truncate(size).map_err(|e| io_error::cond.raise(e));
|
||||
}
|
||||
}
|
||||
|
||||
@ -715,29 +715,68 @@ impl path::Path {
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[allow(unused_imports)]
|
||||
mod test {
|
||||
use prelude::*;
|
||||
use io::{SeekSet, SeekCur, SeekEnd, io_error, Read, Open, ReadWrite};
|
||||
use io::{SeekSet, SeekCur, SeekEnd, io_error, Read, Open,
|
||||
ReadWrite};
|
||||
use io;
|
||||
use str;
|
||||
use super::{File, rmdir, mkdir, readdir, rmdir_recursive, mkdir_recursive,
|
||||
copy, unlink, stat, symlink, link, readlink, chmod,
|
||||
lstat, change_file_times};
|
||||
use io::fs::{File, rmdir, mkdir, readdir, rmdir_recursive,
|
||||
mkdir_recursive, copy, unlink, stat, symlink, link,
|
||||
readlink, chmod, lstat, change_file_times};
|
||||
use util;
|
||||
use path::Path;
|
||||
use io;
|
||||
use ops::Drop;
|
||||
|
||||
fn tmpdir() -> Path {
|
||||
struct TempDir(Path);
|
||||
|
||||
impl Drop for TempDir {
|
||||
fn drop(&mut self) {
|
||||
// Gee, seeing how we're testing the fs module I sure hope that we
|
||||
// at least implement this correctly!
|
||||
io::fs::rmdir_recursive(&**self);
|
||||
}
|
||||
}
|
||||
|
||||
fn tmpdir() -> TempDir {
|
||||
use os;
|
||||
use rand;
|
||||
let ret = os::tmpdir().join(format!("rust-{}", rand::random::<u32>()));
|
||||
mkdir(&ret, io::UserRWX);
|
||||
ret
|
||||
io::fs::mkdir(&ret, io::UserRWX);
|
||||
TempDir(ret)
|
||||
}
|
||||
|
||||
fn free<T>(_: T) {}
|
||||
macro_rules! test (
|
||||
{ fn $name:ident() $b:block } => (
|
||||
mod $name {
|
||||
use prelude::*;
|
||||
use io::{SeekSet, SeekCur, SeekEnd, io_error, Read, Open,
|
||||
ReadWrite};
|
||||
use io;
|
||||
use str;
|
||||
use io::fs::{File, rmdir, mkdir, readdir, rmdir_recursive,
|
||||
mkdir_recursive, copy, unlink, stat, symlink, link,
|
||||
readlink, chmod, lstat, change_file_times};
|
||||
use io::fs::test::tmpdir;
|
||||
use util;
|
||||
|
||||
#[test]
|
||||
fn file_test_io_smoke_test() {
|
||||
fn f() $b
|
||||
|
||||
#[test] fn uv() { f() }
|
||||
#[test] fn native() {
|
||||
use rt::test::run_in_newsched_task;
|
||||
run_in_newsched_task(f);
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
test!(fn file_test_io_smoke_test() {
|
||||
let message = "it's alright. have a good time";
|
||||
let filename = &Path::new("./tmp/file_rt_io_file_test.txt");
|
||||
let tmpdir = tmpdir();
|
||||
let filename = &tmpdir.join("file_rt_io_file_test.txt");
|
||||
{
|
||||
let mut write_stream = File::open_mode(filename, Open, ReadWrite);
|
||||
write_stream.write(message.as_bytes());
|
||||
@ -752,11 +791,11 @@ mod test {
|
||||
assert!(read_str == message.to_owned());
|
||||
}
|
||||
unlink(filename);
|
||||
}
|
||||
})
|
||||
|
||||
#[test]
|
||||
fn file_test_io_invalid_path_opened_without_create_should_raise_condition() {
|
||||
let filename = &Path::new("./tmp/file_that_does_not_exist.txt");
|
||||
test!(fn invalid_path_raises() {
|
||||
let tmpdir = tmpdir();
|
||||
let filename = &tmpdir.join("file_that_does_not_exist.txt");
|
||||
let mut called = false;
|
||||
do io_error::cond.trap(|_| {
|
||||
called = true;
|
||||
@ -765,11 +804,11 @@ mod test {
|
||||
assert!(result.is_none());
|
||||
}
|
||||
assert!(called);
|
||||
}
|
||||
})
|
||||
|
||||
#[test]
|
||||
fn file_test_iounlinking_invalid_path_should_raise_condition() {
|
||||
let filename = &Path::new("./tmp/file_another_file_that_does_not_exist.txt");
|
||||
test!(fn file_test_iounlinking_invalid_path_should_raise_condition() {
|
||||
let tmpdir = tmpdir();
|
||||
let filename = &tmpdir.join("file_another_file_that_does_not_exist.txt");
|
||||
let mut called = false;
|
||||
do io_error::cond.trap(|_| {
|
||||
called = true;
|
||||
@ -777,13 +816,13 @@ mod test {
|
||||
unlink(filename);
|
||||
}
|
||||
assert!(called);
|
||||
}
|
||||
})
|
||||
|
||||
#[test]
|
||||
fn file_test_io_non_positional_read() {
|
||||
test!(fn file_test_io_non_positional_read() {
|
||||
let message = "ten-four";
|
||||
let mut read_mem = [0, .. 8];
|
||||
let filename = &Path::new("./tmp/file_rt_io_file_test_positional.txt");
|
||||
let tmpdir = tmpdir();
|
||||
let filename = &tmpdir.join("file_rt_io_file_test_positional.txt");
|
||||
{
|
||||
let mut rw_stream = File::open_mode(filename, Open, ReadWrite);
|
||||
rw_stream.write(message.as_bytes());
|
||||
@ -802,16 +841,16 @@ mod test {
|
||||
unlink(filename);
|
||||
let read_str = str::from_utf8(read_mem);
|
||||
assert!(read_str == message.to_owned());
|
||||
}
|
||||
})
|
||||
|
||||
#[test]
|
||||
fn file_test_io_seek_and_tell_smoke_test() {
|
||||
test!(fn file_test_io_seek_and_tell_smoke_test() {
|
||||
let message = "ten-four";
|
||||
let mut read_mem = [0, .. 4];
|
||||
let set_cursor = 4 as u64;
|
||||
let mut tell_pos_pre_read;
|
||||
let mut tell_pos_post_read;
|
||||
let filename = &Path::new("./tmp/file_rt_io_file_test_seeking.txt");
|
||||
let tmpdir = tmpdir();
|
||||
let filename = &tmpdir.join("file_rt_io_file_test_seeking.txt");
|
||||
{
|
||||
let mut rw_stream = File::open_mode(filename, Open, ReadWrite);
|
||||
rw_stream.write(message.as_bytes());
|
||||
@ -828,16 +867,16 @@ mod test {
|
||||
assert!(read_str == message.slice(4, 8).to_owned());
|
||||
assert!(tell_pos_pre_read == set_cursor);
|
||||
assert!(tell_pos_post_read == message.len() as u64);
|
||||
}
|
||||
})
|
||||
|
||||
#[test]
|
||||
fn file_test_io_seek_and_write() {
|
||||
test!(fn file_test_io_seek_and_write() {
|
||||
let initial_msg = "food-is-yummy";
|
||||
let overwrite_msg = "-the-bar!!";
|
||||
let final_msg = "foo-the-bar!!";
|
||||
let seek_idx = 3;
|
||||
let mut read_mem = [0, .. 13];
|
||||
let filename = &Path::new("./tmp/file_rt_io_file_test_seek_and_write.txt");
|
||||
let tmpdir = tmpdir();
|
||||
let filename = &tmpdir.join("file_rt_io_file_test_seek_and_write.txt");
|
||||
{
|
||||
let mut rw_stream = File::open_mode(filename, Open, ReadWrite);
|
||||
rw_stream.write(initial_msg.as_bytes());
|
||||
@ -851,17 +890,17 @@ mod test {
|
||||
unlink(filename);
|
||||
let read_str = str::from_utf8(read_mem);
|
||||
assert!(read_str == final_msg.to_owned());
|
||||
}
|
||||
})
|
||||
|
||||
#[test]
|
||||
fn file_test_io_seek_shakedown() {
|
||||
test!(fn file_test_io_seek_shakedown() {
|
||||
use std::str; // 01234567890123
|
||||
let initial_msg = "qwer-asdf-zxcv";
|
||||
let chunk_one = "qwer";
|
||||
let chunk_two = "asdf";
|
||||
let chunk_three = "zxcv";
|
||||
let mut read_mem = [0, .. 4];
|
||||
let filename = &Path::new("./tmp/file_rt_io_file_test_seek_shakedown.txt");
|
||||
let tmpdir = tmpdir();
|
||||
let filename = &tmpdir.join("file_rt_io_file_test_seek_shakedown.txt");
|
||||
{
|
||||
let mut rw_stream = File::open_mode(filename, Open, ReadWrite);
|
||||
rw_stream.write(initial_msg.as_bytes());
|
||||
@ -885,11 +924,11 @@ mod test {
|
||||
assert!(read_str == chunk_one.to_owned());
|
||||
}
|
||||
unlink(filename);
|
||||
}
|
||||
})
|
||||
|
||||
#[test]
|
||||
fn file_test_stat_is_correct_on_is_file() {
|
||||
let filename = &Path::new("./tmp/file_stat_correct_on_is_file.txt");
|
||||
test!(fn file_test_stat_is_correct_on_is_file() {
|
||||
let tmpdir = tmpdir();
|
||||
let filename = &tmpdir.join("file_stat_correct_on_is_file.txt");
|
||||
{
|
||||
let mut fs = File::open_mode(filename, Open, ReadWrite);
|
||||
let msg = "hw";
|
||||
@ -898,49 +937,49 @@ mod test {
|
||||
let stat_res = stat(filename);
|
||||
assert_eq!(stat_res.kind, io::TypeFile);
|
||||
unlink(filename);
|
||||
}
|
||||
})
|
||||
|
||||
#[test]
|
||||
fn file_test_stat_is_correct_on_is_dir() {
|
||||
let filename = &Path::new("./tmp/file_stat_correct_on_is_dir");
|
||||
test!(fn file_test_stat_is_correct_on_is_dir() {
|
||||
let tmpdir = tmpdir();
|
||||
let filename = &tmpdir.join("file_stat_correct_on_is_dir");
|
||||
mkdir(filename, io::UserRWX);
|
||||
let stat_res = filename.stat();
|
||||
assert!(stat_res.kind == io::TypeDirectory);
|
||||
rmdir(filename);
|
||||
}
|
||||
})
|
||||
|
||||
#[test]
|
||||
fn file_test_fileinfo_false_when_checking_is_file_on_a_directory() {
|
||||
let dir = &Path::new("./tmp/fileinfo_false_on_dir");
|
||||
test!(fn file_test_fileinfo_false_when_checking_is_file_on_a_directory() {
|
||||
let tmpdir = tmpdir();
|
||||
let dir = &tmpdir.join("fileinfo_false_on_dir");
|
||||
mkdir(dir, io::UserRWX);
|
||||
assert!(dir.is_file() == false);
|
||||
rmdir(dir);
|
||||
}
|
||||
})
|
||||
|
||||
#[test]
|
||||
fn file_test_fileinfo_check_exists_before_and_after_file_creation() {
|
||||
let file = &Path::new("./tmp/fileinfo_check_exists_b_and_a.txt");
|
||||
test!(fn file_test_fileinfo_check_exists_before_and_after_file_creation() {
|
||||
let tmpdir = tmpdir();
|
||||
let file = &tmpdir.join("fileinfo_check_exists_b_and_a.txt");
|
||||
File::create(file).write(bytes!("foo"));
|
||||
assert!(file.exists());
|
||||
unlink(file);
|
||||
assert!(!file.exists());
|
||||
}
|
||||
})
|
||||
|
||||
#[test]
|
||||
fn file_test_directoryinfo_check_exists_before_and_after_mkdir() {
|
||||
let dir = &Path::new("./tmp/before_and_after_dir");
|
||||
test!(fn file_test_directoryinfo_check_exists_before_and_after_mkdir() {
|
||||
let tmpdir = tmpdir();
|
||||
let dir = &tmpdir.join("before_and_after_dir");
|
||||
assert!(!dir.exists());
|
||||
mkdir(dir, io::UserRWX);
|
||||
assert!(dir.exists());
|
||||
assert!(dir.is_dir());
|
||||
rmdir(dir);
|
||||
assert!(!dir.exists());
|
||||
}
|
||||
})
|
||||
|
||||
#[test]
|
||||
fn file_test_directoryinfo_readdir() {
|
||||
test!(fn file_test_directoryinfo_readdir() {
|
||||
use std::str;
|
||||
let dir = &Path::new("./tmp/di_readdir");
|
||||
let tmpdir = tmpdir();
|
||||
let dir = &tmpdir.join("di_readdir");
|
||||
mkdir(dir, io::UserRWX);
|
||||
let prefix = "foo";
|
||||
for n in range(0,3) {
|
||||
@ -966,15 +1005,13 @@ mod test {
|
||||
unlink(f);
|
||||
}
|
||||
rmdir(dir);
|
||||
}
|
||||
})
|
||||
|
||||
#[test]
|
||||
fn recursive_mkdir_slash() {
|
||||
test!(fn recursive_mkdir_slash() {
|
||||
mkdir_recursive(&Path::new("/"), io::UserRWX);
|
||||
}
|
||||
})
|
||||
|
||||
#[test]
|
||||
fn unicode_path_is_dir() {
|
||||
test!(fn unicode_path_is_dir() {
|
||||
assert!(Path::new(".").is_dir());
|
||||
assert!(!Path::new("test/stdtest/fs.rs").is_dir());
|
||||
|
||||
@ -990,12 +1027,9 @@ mod test {
|
||||
File::create(&filepath); // ignore return; touch only
|
||||
assert!(!filepath.is_dir());
|
||||
assert!(filepath.exists());
|
||||
})
|
||||
|
||||
rmdir_recursive(&tmpdir);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unicode_path_exists() {
|
||||
test!(fn unicode_path_exists() {
|
||||
assert!(Path::new(".").exists());
|
||||
assert!(!Path::new("test/nonexistent-bogus-path").exists());
|
||||
|
||||
@ -1005,11 +1039,9 @@ mod 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() {
|
||||
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)) {
|
||||
@ -1019,10 +1051,9 @@ mod test {
|
||||
assert!(!to.exists());
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
#[test]
|
||||
fn copy_file_ok() {
|
||||
test!(fn copy_file_ok() {
|
||||
let tmpdir = tmpdir();
|
||||
let input = tmpdir.join("in.txt");
|
||||
let out = tmpdir.join("out.txt");
|
||||
@ -1033,23 +1064,19 @@ mod test {
|
||||
assert_eq!(contents.as_slice(), bytes!("hello"));
|
||||
|
||||
assert_eq!(input.stat().perm, out.stat().perm);
|
||||
rmdir_recursive(&tmpdir);
|
||||
}
|
||||
})
|
||||
|
||||
#[test]
|
||||
fn copy_file_dst_dir() {
|
||||
test!(fn copy_file_dst_dir() {
|
||||
let tmpdir = tmpdir();
|
||||
let out = tmpdir.join("out");
|
||||
|
||||
File::create(&out);
|
||||
match io::result(|| copy(&out, &tmpdir)) {
|
||||
match io::result(|| copy(&out, &*tmpdir)) {
|
||||
Ok(*) => fail!(), Err(*) => {}
|
||||
}
|
||||
rmdir_recursive(&tmpdir);
|
||||
}
|
||||
})
|
||||
|
||||
#[test]
|
||||
fn copy_file_dst_exists() {
|
||||
test!(fn copy_file_dst_exists() {
|
||||
let tmpdir = tmpdir();
|
||||
let input = tmpdir.join("in");
|
||||
let output = tmpdir.join("out");
|
||||
@ -1060,24 +1087,19 @@ mod test {
|
||||
|
||||
assert_eq!(File::open(&output).read_to_end(),
|
||||
(bytes!("foo")).to_owned());
|
||||
})
|
||||
|
||||
rmdir_recursive(&tmpdir);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn copy_file_src_dir() {
|
||||
test!(fn copy_file_src_dir() {
|
||||
let tmpdir = tmpdir();
|
||||
let out = tmpdir.join("out");
|
||||
|
||||
match io::result(|| copy(&tmpdir, &out)) {
|
||||
match io::result(|| copy(&*tmpdir, &out)) {
|
||||
Ok(*) => fail!(), Err(*) => {}
|
||||
}
|
||||
assert!(!out.exists());
|
||||
rmdir_recursive(&tmpdir);
|
||||
}
|
||||
})
|
||||
|
||||
#[test]
|
||||
fn copy_file_preserves_perm_bits() {
|
||||
test!(fn copy_file_preserves_perm_bits() {
|
||||
let tmpdir = tmpdir();
|
||||
let input = tmpdir.join("in.txt");
|
||||
let out = tmpdir.join("out.txt");
|
||||
@ -1089,56 +1111,51 @@ mod test {
|
||||
|
||||
chmod(&input, io::UserFile);
|
||||
chmod(&out, io::UserFile);
|
||||
rmdir_recursive(&tmpdir);
|
||||
}
|
||||
})
|
||||
|
||||
#[test]
|
||||
#[ignore(cfg(windows))] // FIXME(#10264) operation not permitted?
|
||||
fn symlinks_work() {
|
||||
#[cfg(not(windows))] // FIXME(#10264) operation not permitted?
|
||||
test!(fn symlinks_work() {
|
||||
let tmpdir = tmpdir();
|
||||
let input = tmpdir.join("in.txt");
|
||||
let out = tmpdir.join("out.txt");
|
||||
|
||||
File::create(&input).write("foobar".as_bytes());
|
||||
symlink(&input, &out);
|
||||
assert_eq!(lstat(&out).kind, io::TypeSymlink);
|
||||
if cfg!(not(windows)) {
|
||||
assert_eq!(lstat(&out).kind, io::TypeSymlink);
|
||||
}
|
||||
assert_eq!(stat(&out).size, stat(&input).size);
|
||||
assert_eq!(File::open(&out).read_to_end(), (bytes!("foobar")).to_owned());
|
||||
})
|
||||
|
||||
rmdir_recursive(&tmpdir);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore(cfg(windows))] // apparently windows doesn't like symlinks
|
||||
fn symlink_noexist() {
|
||||
#[cfg(not(windows))] // apparently windows doesn't like symlinks
|
||||
test!(fn symlink_noexist() {
|
||||
let tmpdir = tmpdir();
|
||||
// symlinks can point to things that don't exist
|
||||
symlink(&tmpdir.join("foo"), &tmpdir.join("bar"));
|
||||
assert!(readlink(&tmpdir.join("bar")).unwrap() == tmpdir.join("foo"));
|
||||
rmdir_recursive(&tmpdir);
|
||||
}
|
||||
})
|
||||
|
||||
#[test]
|
||||
fn readlink_not_symlink() {
|
||||
test!(fn readlink_not_symlink() {
|
||||
let tmpdir = tmpdir();
|
||||
match io::result(|| readlink(&tmpdir)) {
|
||||
match io::result(|| readlink(&*tmpdir)) {
|
||||
Ok(*) => fail!("wanted a failure"),
|
||||
Err(*) => {}
|
||||
}
|
||||
rmdir_recursive(&tmpdir);
|
||||
}
|
||||
})
|
||||
|
||||
#[test]
|
||||
fn links_work() {
|
||||
test!(fn links_work() {
|
||||
let tmpdir = tmpdir();
|
||||
let input = tmpdir.join("in.txt");
|
||||
let out = tmpdir.join("out.txt");
|
||||
|
||||
File::create(&input).write("foobar".as_bytes());
|
||||
link(&input, &out);
|
||||
assert_eq!(lstat(&out).kind, io::TypeFile);
|
||||
if cfg!(not(windows)) {
|
||||
assert_eq!(lstat(&out).kind, io::TypeFile);
|
||||
assert_eq!(stat(&out).unstable.nlink, 2);
|
||||
}
|
||||
assert_eq!(stat(&out).size, stat(&input).size);
|
||||
assert_eq!(stat(&out).unstable.nlink, 2);
|
||||
assert_eq!(File::open(&out).read_to_end(), (bytes!("foobar")).to_owned());
|
||||
|
||||
// can't link to yourself
|
||||
@ -1151,12 +1168,9 @@ mod test {
|
||||
Ok(*) => fail!("wanted a failure"),
|
||||
Err(*) => {}
|
||||
}
|
||||
})
|
||||
|
||||
rmdir_recursive(&tmpdir);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn chmod_works() {
|
||||
test!(fn chmod_works() {
|
||||
let tmpdir = tmpdir();
|
||||
let file = tmpdir.join("in.txt");
|
||||
|
||||
@ -1171,11 +1185,9 @@ mod test {
|
||||
}
|
||||
|
||||
chmod(&file, io::UserFile);
|
||||
rmdir_recursive(&tmpdir);
|
||||
}
|
||||
})
|
||||
|
||||
#[test]
|
||||
fn sync_doesnt_kill_anything() {
|
||||
test!(fn sync_doesnt_kill_anything() {
|
||||
let tmpdir = tmpdir();
|
||||
let path = tmpdir.join("in.txt");
|
||||
|
||||
@ -1185,24 +1197,23 @@ mod test {
|
||||
file.write(bytes!("foo"));
|
||||
file.fsync();
|
||||
file.datasync();
|
||||
free(file);
|
||||
util::ignore(file);
|
||||
})
|
||||
|
||||
rmdir_recursive(&tmpdir);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn truncate_works() {
|
||||
test!(fn truncate_works() {
|
||||
let tmpdir = tmpdir();
|
||||
let path = tmpdir.join("in.txt");
|
||||
|
||||
let mut file = File::open_mode(&path, io::Open, io::ReadWrite).unwrap();
|
||||
file.write(bytes!("foo"));
|
||||
file.fsync();
|
||||
|
||||
// Do some simple things with truncation
|
||||
assert_eq!(stat(&path).size, 3);
|
||||
file.truncate(10);
|
||||
assert_eq!(stat(&path).size, 10);
|
||||
file.write(bytes!("bar"));
|
||||
file.fsync();
|
||||
assert_eq!(stat(&path).size, 10);
|
||||
assert_eq!(File::open(&path).read_to_end(),
|
||||
(bytes!("foobar", 0, 0, 0, 0)).to_owned());
|
||||
@ -1213,16 +1224,14 @@ mod test {
|
||||
file.truncate(2);
|
||||
assert_eq!(stat(&path).size, 2);
|
||||
file.write(bytes!("wut"));
|
||||
file.fsync();
|
||||
assert_eq!(stat(&path).size, 9);
|
||||
assert_eq!(File::open(&path).read_to_end(),
|
||||
(bytes!("fo", 0, 0, 0, 0, "wut")).to_owned());
|
||||
free(file);
|
||||
util::ignore(file);
|
||||
})
|
||||
|
||||
rmdir_recursive(&tmpdir);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn open_flavors() {
|
||||
test!(fn open_flavors() {
|
||||
let tmpdir = tmpdir();
|
||||
|
||||
match io::result(|| File::open_mode(&tmpdir.join("a"), io::Open,
|
||||
@ -1258,9 +1267,7 @@ mod test {
|
||||
f.write("bar".as_bytes());
|
||||
}
|
||||
assert_eq!(stat(&tmpdir.join("h")).size, 3);
|
||||
|
||||
rmdir_recursive(&tmpdir);
|
||||
}
|
||||
})
|
||||
|
||||
#[test]
|
||||
fn utime() {
|
||||
@ -1271,8 +1278,6 @@ mod test {
|
||||
change_file_times(&path, 1000, 2000);
|
||||
assert_eq!(path.stat().accessed, 1000);
|
||||
assert_eq!(path.stat().modified, 2000);
|
||||
|
||||
rmdir_recursive(&tmpdir);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -1283,7 +1288,5 @@ mod test {
|
||||
Ok(*) => fail!(),
|
||||
Err(*) => {}
|
||||
}
|
||||
|
||||
rmdir_recursive(&tmpdir);
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -90,6 +90,24 @@ fn last_error() -> IoError {
|
||||
}
|
||||
}
|
||||
|
||||
// unix has nonzero values as errors
|
||||
fn mkerr_libc(ret: libc::c_int) -> IoResult<()> {
|
||||
if ret != 0 {
|
||||
Err(last_error())
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
// windows has zero values as errors
|
||||
fn mkerr_winbool(ret: libc::c_int) -> IoResult<()> {
|
||||
if ret == 0 {
|
||||
Err(last_error())
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Implementation of rt::rtio's IoFactory trait to generate handles to the
|
||||
/// native I/O functionality.
|
||||
pub struct IoFactory;
|
||||
@ -125,51 +143,51 @@ impl rtio::IoFactory for IoFactory {
|
||||
};
|
||||
~file::FileDesc::new(fd, close) as ~RtioFileStream
|
||||
}
|
||||
fn fs_open(&mut self, _path: &CString, _fm: io::FileMode, _fa: io::FileAccess)
|
||||
fn fs_open(&mut self, path: &CString, fm: io::FileMode, fa: io::FileAccess)
|
||||
-> IoResult<~RtioFileStream> {
|
||||
Err(unimpl())
|
||||
file::open(path, fm, fa).map(|fd| ~fd as ~RtioFileStream)
|
||||
}
|
||||
fn fs_unlink(&mut self, _path: &CString) -> IoResult<()> {
|
||||
Err(unimpl())
|
||||
fn fs_unlink(&mut self, path: &CString) -> IoResult<()> {
|
||||
file::unlink(path)
|
||||
}
|
||||
fn fs_stat(&mut self, _path: &CString) -> IoResult<io::FileStat> {
|
||||
Err(unimpl())
|
||||
fn fs_stat(&mut self, path: &CString) -> IoResult<io::FileStat> {
|
||||
file::stat(path)
|
||||
}
|
||||
fn fs_mkdir(&mut self, _path: &CString,
|
||||
_mode: io::FilePermission) -> IoResult<()> {
|
||||
Err(unimpl())
|
||||
fn fs_mkdir(&mut self, path: &CString,
|
||||
mode: io::FilePermission) -> IoResult<()> {
|
||||
file::mkdir(path, mode)
|
||||
}
|
||||
fn fs_chmod(&mut self, _path: &CString,
|
||||
_mode: io::FilePermission) -> IoResult<()> {
|
||||
Err(unimpl())
|
||||
fn fs_chmod(&mut self, path: &CString,
|
||||
mode: io::FilePermission) -> IoResult<()> {
|
||||
file::chmod(path, mode)
|
||||
}
|
||||
fn fs_rmdir(&mut self, _path: &CString) -> IoResult<()> {
|
||||
Err(unimpl())
|
||||
fn fs_rmdir(&mut self, path: &CString) -> IoResult<()> {
|
||||
file::rmdir(path)
|
||||
}
|
||||
fn fs_rename(&mut self, _path: &CString, _to: &CString) -> IoResult<()> {
|
||||
Err(unimpl())
|
||||
fn fs_rename(&mut self, path: &CString, to: &CString) -> IoResult<()> {
|
||||
file::rename(path, to)
|
||||
}
|
||||
fn fs_readdir(&mut self, _path: &CString, _flags: c_int) -> IoResult<~[Path]> {
|
||||
Err(unimpl())
|
||||
fn fs_readdir(&mut self, path: &CString, _flags: c_int) -> IoResult<~[Path]> {
|
||||
file::readdir(path)
|
||||
}
|
||||
fn fs_lstat(&mut self, _path: &CString) -> IoResult<io::FileStat> {
|
||||
Err(unimpl())
|
||||
fn fs_lstat(&mut self, path: &CString) -> IoResult<io::FileStat> {
|
||||
file::lstat(path)
|
||||
}
|
||||
fn fs_chown(&mut self, _path: &CString, _uid: int, _gid: int) -> IoResult<()> {
|
||||
Err(unimpl())
|
||||
fn fs_chown(&mut self, path: &CString, uid: int, gid: int) -> IoResult<()> {
|
||||
file::chown(path, uid, gid)
|
||||
}
|
||||
fn fs_readlink(&mut self, _path: &CString) -> IoResult<Path> {
|
||||
Err(unimpl())
|
||||
fn fs_readlink(&mut self, path: &CString) -> IoResult<Path> {
|
||||
file::readlink(path)
|
||||
}
|
||||
fn fs_symlink(&mut self, _src: &CString, _dst: &CString) -> IoResult<()> {
|
||||
Err(unimpl())
|
||||
fn fs_symlink(&mut self, src: &CString, dst: &CString) -> IoResult<()> {
|
||||
file::symlink(src, dst)
|
||||
}
|
||||
fn fs_link(&mut self, _src: &CString, _dst: &CString) -> IoResult<()> {
|
||||
Err(unimpl())
|
||||
fn fs_link(&mut self, src: &CString, dst: &CString) -> IoResult<()> {
|
||||
file::link(src, dst)
|
||||
}
|
||||
fn fs_utime(&mut self, _src: &CString, _atime: u64,
|
||||
_mtime: u64) -> IoResult<()> {
|
||||
Err(unimpl())
|
||||
fn fs_utime(&mut self, src: &CString, atime: u64,
|
||||
mtime: u64) -> IoResult<()> {
|
||||
file::utime(src, atime, mtime)
|
||||
}
|
||||
|
||||
// misc
|
||||
@ -183,14 +201,18 @@ impl rtio::IoFactory for IoFactory {
|
||||
io.move_iter().map(|p| p.map(|p| ~p as ~RtioPipe)).collect())
|
||||
})
|
||||
}
|
||||
fn pipe_open(&mut self, _fd: c_int) -> IoResult<~RtioPipe> {
|
||||
Err(unimpl())
|
||||
fn pipe_open(&mut self, fd: c_int) -> IoResult<~RtioPipe> {
|
||||
Ok(~file::FileDesc::new(fd, true) as ~RtioPipe)
|
||||
}
|
||||
fn tty_open(&mut self, fd: c_int, _readable: bool) -> IoResult<~RtioTTY> {
|
||||
if unsafe { libc::isatty(fd) } != 0 {
|
||||
Ok(~file::FileDesc::new(fd, true) as ~RtioTTY)
|
||||
} else {
|
||||
Err(unimpl())
|
||||
Err(IoError {
|
||||
kind: io::MismatchedFileTypeForOperation,
|
||||
desc: "file descriptor is not a TTY",
|
||||
detail: None,
|
||||
})
|
||||
}
|
||||
}
|
||||
fn signal(&mut self, _signal: Signum, _channel: SharedChan<Signum>)
|
||||
|
@ -316,12 +316,22 @@ impl Writer for StdWriter {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use rt::test::run_in_newsched_task;
|
||||
|
||||
#[test]
|
||||
fn smoke() {
|
||||
fn smoke_uv() {
|
||||
// Just make sure we can acquire handles
|
||||
stdin();
|
||||
stdout();
|
||||
stderr();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn smoke_native() {
|
||||
do run_in_newsched_task {
|
||||
stdin();
|
||||
stdout();
|
||||
stderr();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -329,6 +329,11 @@ pub mod types {
|
||||
__unused5: c_long,
|
||||
}
|
||||
|
||||
pub struct utimbuf {
|
||||
actime: time_t,
|
||||
modtime: time_t,
|
||||
}
|
||||
|
||||
pub struct pthread_attr_t {
|
||||
__size: [u32, ..9]
|
||||
}
|
||||
@ -365,6 +370,11 @@ pub mod types {
|
||||
st_ino: c_ulonglong
|
||||
}
|
||||
|
||||
pub struct utimbuf {
|
||||
actime: time_t,
|
||||
modtime: time_t,
|
||||
}
|
||||
|
||||
pub struct pthread_attr_t {
|
||||
__size: [u32, ..9]
|
||||
}
|
||||
@ -403,6 +413,11 @@ pub mod types {
|
||||
st_pad5: [c_long, ..14],
|
||||
}
|
||||
|
||||
pub struct utimbuf {
|
||||
actime: time_t,
|
||||
modtime: time_t,
|
||||
}
|
||||
|
||||
pub struct pthread_attr_t {
|
||||
__size: [u32, ..9]
|
||||
}
|
||||
@ -479,6 +494,11 @@ pub mod types {
|
||||
__unused: [c_long, ..3],
|
||||
}
|
||||
|
||||
pub struct utimbuf {
|
||||
actime: time_t,
|
||||
modtime: time_t,
|
||||
}
|
||||
|
||||
pub struct pthread_attr_t {
|
||||
__size: [u64, ..7]
|
||||
}
|
||||
@ -594,6 +614,11 @@ pub mod types {
|
||||
__unused: [uint8_t, ..2],
|
||||
}
|
||||
|
||||
pub struct utimbuf {
|
||||
actime: time_t,
|
||||
modtime: time_t,
|
||||
}
|
||||
|
||||
pub type pthread_attr_t = *c_void;
|
||||
}
|
||||
pub mod posix08 {
|
||||
@ -629,6 +654,12 @@ pub mod types {
|
||||
st_mtime: time64_t,
|
||||
st_ctime: time64_t,
|
||||
}
|
||||
|
||||
// note that this is called utimbuf64 in win32
|
||||
pub struct utimbuf {
|
||||
actime: time64_t,
|
||||
modtime: time64_t,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -679,7 +710,7 @@ pub mod types {
|
||||
use libc::types::os::arch::c95::{c_char, c_int, c_uint, size_t};
|
||||
use libc::types::os::arch::c95::{c_long, c_ulong};
|
||||
use libc::types::os::arch::c95::{wchar_t};
|
||||
use libc::types::os::arch::c99::{c_ulonglong};
|
||||
use libc::types::os::arch::c99::{c_ulonglong, c_longlong};
|
||||
|
||||
pub type BOOL = c_int;
|
||||
pub type BYTE = u8;
|
||||
@ -692,8 +723,13 @@ pub mod types {
|
||||
pub type HANDLE = LPVOID;
|
||||
pub type HMODULE = c_uint;
|
||||
|
||||
pub type LONG = c_long;
|
||||
pub type PLONG = *mut c_long;
|
||||
pub type LONG_PTR = c_long;
|
||||
|
||||
pub type LARGE_INTEGER = c_longlong;
|
||||
pub type PLARGE_INTEGER = *mut c_longlong;
|
||||
|
||||
pub type LPCWSTR = *WCHAR;
|
||||
pub type LPCSTR = *CHAR;
|
||||
pub type LPCTSTR = *CHAR;
|
||||
@ -795,6 +831,16 @@ pub mod types {
|
||||
Type: DWORD
|
||||
}
|
||||
pub type LPMEMORY_BASIC_INFORMATION = *mut MEMORY_BASIC_INFORMATION;
|
||||
|
||||
pub struct OVERLAPPED {
|
||||
Internal: *c_ulong,
|
||||
InternalHigh: *c_ulong,
|
||||
Offset: DWORD,
|
||||
OffsetHigh: DWORD,
|
||||
hEvent: HANDLE,
|
||||
}
|
||||
|
||||
pub type LPOVERLAPPED = *mut OVERLAPPED;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1065,6 +1111,11 @@ pub mod types {
|
||||
st_qspare: [int64_t, ..2],
|
||||
}
|
||||
|
||||
pub struct utimbuf {
|
||||
actime: time_t,
|
||||
modtime: time_t,
|
||||
}
|
||||
|
||||
pub struct pthread_attr_t {
|
||||
__sig: c_long,
|
||||
__opaque: [c_char, ..36]
|
||||
@ -1151,6 +1202,11 @@ pub mod types {
|
||||
st_qspare: [int64_t, ..2],
|
||||
}
|
||||
|
||||
pub struct utimbuf {
|
||||
actime: time_t,
|
||||
modtime: time_t,
|
||||
}
|
||||
|
||||
pub struct pthread_attr_t {
|
||||
__sig: c_long,
|
||||
__opaque: [c_char, ..56]
|
||||
@ -1337,6 +1393,72 @@ pub mod consts {
|
||||
pub static PROCESSOR_ARCHITECTURE_IA64 : WORD = 6;
|
||||
pub static PROCESSOR_ARCHITECTURE_AMD64 : WORD = 9;
|
||||
pub static PROCESSOR_ARCHITECTURE_UNKNOWN : WORD = 0xffff;
|
||||
|
||||
pub static MOVEFILE_COPY_ALLOWED: DWORD = 2;
|
||||
pub static MOVEFILE_CREATE_HARDLINK: DWORD = 16;
|
||||
pub static MOVEFILE_DELAY_UNTIL_REBOOT: DWORD = 4;
|
||||
pub static MOVEFILE_FAIL_IF_NOT_TRACKABLE: DWORD = 32;
|
||||
pub static MOVEFILE_REPLACE_EXISTING: DWORD = 1;
|
||||
pub static MOVEFILE_WRITE_THROUGH: DWORD = 8;
|
||||
|
||||
pub static SYMBOLIC_LINK_FLAG_DIRECTORY: DWORD = 1;
|
||||
|
||||
pub static FILE_SHARE_DELETE: DWORD = 0x4;
|
||||
pub static FILE_SHARE_READ: DWORD = 0x1;
|
||||
pub static FILE_SHARE_WRITE: DWORD = 0x2;
|
||||
|
||||
pub static CREATE_ALWAYS: DWORD = 2;
|
||||
pub static CREATE_NEW: DWORD = 1;
|
||||
pub static OPEN_ALWAYS: DWORD = 4;
|
||||
pub static OPEN_EXISTING: DWORD = 3;
|
||||
pub static TRUNCATE_EXISTING: DWORD = 5;
|
||||
|
||||
pub static FILE_ATTRIBUTE_ARCHIVE: DWORD = 0x20;
|
||||
pub static FILE_ATTRIBUTE_COMPRESSED: DWORD = 0x800;
|
||||
pub static FILE_ATTRIBUTE_DEVICE: DWORD = 0x40;
|
||||
pub static FILE_ATTRIBUTE_DIRECTORY: DWORD = 0x10;
|
||||
pub static FILE_ATTRIBUTE_ENCRYPTED: DWORD = 0x4000;
|
||||
pub static FILE_ATTRIBUTE_HIDDEN: DWORD = 0x2;
|
||||
pub static FILE_ATTRIBUTE_INTEGRITY_STREAM: DWORD = 0x8000;
|
||||
pub static FILE_ATTRIBUTE_NORMAL: DWORD = 0x80;
|
||||
pub static FILE_ATTRIBUTE_NOT_CONTENT_INDEXED: DWORD = 0x2000;
|
||||
pub static FILE_ATTRIBUTE_NO_SCRUB_DATA: DWORD = 0x20000;
|
||||
pub static FILE_ATTRIBUTE_OFFLINE: DWORD = 0x1000;
|
||||
pub static FILE_ATTRIBUTE_READONLY: DWORD = 0x1;
|
||||
pub static FILE_ATTRIBUTE_REPARSE_POINT: DWORD = 0x400;
|
||||
pub static FILE_ATTRIBUTE_SPARSE_FILE: DWORD = 0x200;
|
||||
pub static FILE_ATTRIBUTE_SYSTEM: DWORD = 0x4;
|
||||
pub static FILE_ATTRIBUTE_TEMPORARY: DWORD = 0x100;
|
||||
pub static FILE_ATTRIBUTE_VIRTUAL: DWORD = 0x10000;
|
||||
|
||||
pub static FILE_FLAG_BACKUP_SEMANTICS: DWORD = 0x02000000;
|
||||
pub static FILE_FLAG_DELETE_ON_CLOSE: DWORD = 0x04000000;
|
||||
pub static FILE_FLAG_NO_BUFFERING: DWORD = 0x20000000;
|
||||
pub static FILE_FLAG_OPEN_NO_RECALL: DWORD = 0x00100000;
|
||||
pub static FILE_FLAG_OPEN_REPARSE_POINT: DWORD = 0x00200000;
|
||||
pub static FILE_FLAG_OVERLAPPED: DWORD = 0x40000000;
|
||||
pub static FILE_FLAG_POSIX_SEMANTICS: DWORD = 0x0100000;
|
||||
pub static FILE_FLAG_RANDOM_ACCESS: DWORD = 0x10000000;
|
||||
pub static FILE_FLAG_SESSION_AWARE: DWORD = 0x00800000;
|
||||
pub static FILE_FLAG_SEQUENTIAL_SCAN: DWORD = 0x08000000;
|
||||
pub static FILE_FLAG_WRITE_THROUGH: DWORD = 0x80000000;
|
||||
|
||||
pub static FILE_NAME_NORMALIZED: DWORD = 0x0;
|
||||
pub static FILE_NAME_OPENED: DWORD = 0x8;
|
||||
|
||||
pub static VOLUME_NAME_DOS: DWORD = 0x0;
|
||||
pub static VOLUME_NAME_GUID: DWORD = 0x1;
|
||||
pub static VOLUME_NAME_NONE: DWORD = 0x4;
|
||||
pub static VOLUME_NAME_NT: DWORD = 0x2;
|
||||
|
||||
pub static GENERIC_READ: DWORD = 0x80000000;
|
||||
pub static GENERIC_WRITE: DWORD = 0x40000000;
|
||||
pub static GENERIC_EXECUTE: DWORD = 0x20000000;
|
||||
pub static GENERIC_ALL: DWORD = 0x10000000;
|
||||
|
||||
pub static FILE_BEGIN: DWORD = 0;
|
||||
pub static FILE_CURRENT: DWORD = 1;
|
||||
pub static FILE_END: DWORD = 2;
|
||||
}
|
||||
pub mod sysconf {
|
||||
}
|
||||
@ -2873,18 +2995,26 @@ pub mod funcs {
|
||||
pub mod posix88 {
|
||||
#[nolink]
|
||||
pub mod stat_ {
|
||||
use libc::types::os::common::posix01::stat;
|
||||
use libc::types::os::arch::c95::{c_int, c_char};
|
||||
use libc::types::os::common::posix01::{stat, utimbuf};
|
||||
use libc::types::os::arch::c95::{c_int, c_char, wchar_t};
|
||||
|
||||
extern {
|
||||
#[link_name = "_chmod"]
|
||||
pub fn chmod(path: *c_char, mode: c_int) -> c_int;
|
||||
#[link_name = "_wchmod"]
|
||||
pub fn wchmod(path: *wchar_t, mode: c_int) -> c_int;
|
||||
#[link_name = "_mkdir"]
|
||||
pub fn mkdir(path: *c_char) -> c_int;
|
||||
#[link_name = "_wrmdir"]
|
||||
pub fn wrmdir(path: *wchar_t) -> c_int;
|
||||
#[link_name = "_fstat64"]
|
||||
pub fn fstat(fildes: c_int, buf: *mut stat) -> c_int;
|
||||
#[link_name = "_stat64"]
|
||||
pub fn stat(path: *c_char, buf: *mut stat) -> c_int;
|
||||
#[link_name = "_wstat64"]
|
||||
pub fn wstat(path: *wchar_t, buf: *mut stat) -> c_int;
|
||||
#[link_name = "_wutime64"]
|
||||
pub fn wutime(file: *wchar_t, buf: *utimbuf) -> c_int;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2907,11 +3037,14 @@ pub mod funcs {
|
||||
|
||||
#[nolink]
|
||||
pub mod fcntl {
|
||||
use libc::types::os::arch::c95::{c_int, c_char};
|
||||
use libc::types::os::arch::c95::{c_int, c_char, wchar_t};
|
||||
extern {
|
||||
#[link_name = "_open"]
|
||||
pub fn open(path: *c_char, oflag: c_int, mode: c_int)
|
||||
-> c_int;
|
||||
#[link_name = "_wopen"]
|
||||
pub fn wopen(path: *wchar_t, oflag: c_int, mode: c_int)
|
||||
-> c_int;
|
||||
#[link_name = "_creat"]
|
||||
pub fn creat(path: *c_char, mode: c_int) -> c_int;
|
||||
}
|
||||
@ -3079,9 +3212,12 @@ pub mod funcs {
|
||||
use libc::types::common::c95::c_void;
|
||||
use libc::types::os::arch::c95::{c_char, c_int, c_long, c_uint};
|
||||
use libc::types::os::arch::c95::{size_t};
|
||||
use libc::types::os::arch::posix01::utimbuf;
|
||||
use libc::types::os::arch::posix88::{gid_t, off_t, pid_t};
|
||||
use libc::types::os::arch::posix88::{ssize_t, uid_t};
|
||||
|
||||
pub static _PC_NAME_MAX: c_int = 4;
|
||||
|
||||
extern {
|
||||
pub fn access(path: *c_char, amode: c_int) -> c_int;
|
||||
pub fn alarm(seconds: c_uint) -> c_uint;
|
||||
@ -3130,6 +3266,11 @@ pub mod funcs {
|
||||
pub fn unlink(c: *c_char) -> c_int;
|
||||
pub fn write(fd: c_int, buf: *c_void, count: size_t)
|
||||
-> ssize_t;
|
||||
pub fn pread(fd: c_int, buf: *c_void, count: size_t,
|
||||
offset: off_t) -> ssize_t;
|
||||
pub fn pwrite(fd: c_int, buf: *c_void, count: size_t,
|
||||
offset: off_t) -> ssize_t;
|
||||
pub fn utime(file: *c_char, buf: *utimbuf) -> c_int;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3201,7 +3342,7 @@ pub mod funcs {
|
||||
#[nolink]
|
||||
pub mod unistd {
|
||||
use libc::types::os::arch::c95::{c_char, c_int, size_t};
|
||||
use libc::types::os::arch::posix88::{ssize_t};
|
||||
use libc::types::os::arch::posix88::{ssize_t, off_t};
|
||||
|
||||
extern {
|
||||
pub fn readlink(path: *c_char,
|
||||
@ -3221,6 +3362,8 @@ pub mod funcs {
|
||||
pub fn putenv(string: *c_char) -> c_int;
|
||||
|
||||
pub fn symlink(path1: *c_char, path2: *c_char) -> c_int;
|
||||
|
||||
pub fn ftruncate(fd: c_int, length: off_t) -> c_int;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3374,12 +3517,13 @@ pub mod funcs {
|
||||
use libc::types::os::arch::extra::{BOOL, DWORD, SIZE_T, HMODULE};
|
||||
use libc::types::os::arch::extra::{LPCWSTR, LPWSTR, LPCTSTR,
|
||||
LPTSTR, LPTCH, LPDWORD, LPVOID,
|
||||
LPCVOID};
|
||||
LPCVOID, LPOVERLAPPED};
|
||||
use libc::types::os::arch::extra::{LPSECURITY_ATTRIBUTES, LPSTARTUPINFO,
|
||||
LPPROCESS_INFORMATION,
|
||||
LPMEMORY_BASIC_INFORMATION,
|
||||
LPSYSTEM_INFO};
|
||||
use libc::types::os::arch::extra::{HANDLE, LPHANDLE};
|
||||
use libc::types::os::arch::extra::{HANDLE, LPHANDLE, LARGE_INTEGER,
|
||||
PLARGE_INTEGER};
|
||||
|
||||
extern "system" {
|
||||
pub fn GetEnvironmentVariableW(n: LPCWSTR,
|
||||
@ -3486,6 +3630,43 @@ pub mod funcs {
|
||||
dwNumberOfBytesToMap: SIZE_T)
|
||||
-> LPVOID;
|
||||
pub fn UnmapViewOfFile(lpBaseAddress: LPCVOID) -> BOOL;
|
||||
pub fn MoveFileExW(lpExistingFileName: LPCWSTR,
|
||||
lpNewFileName: LPCWSTR,
|
||||
dwFlags: DWORD) -> BOOL;
|
||||
pub fn CreateSymbolicLinkW(lpSymlinkFileName: LPCWSTR,
|
||||
lpTargetFileName: LPCWSTR,
|
||||
dwFlags: DWORD) -> BOOL;
|
||||
pub fn CreateHardLinkW(lpSymlinkFileName: LPCWSTR,
|
||||
lpTargetFileName: LPCWSTR,
|
||||
lpSecurityAttributes: LPSECURITY_ATTRIBUTES)
|
||||
-> BOOL;
|
||||
pub fn FlushFileBuffers(hFile: HANDLE) -> BOOL;
|
||||
pub fn CreateFileW(lpFileName: LPCWSTR,
|
||||
dwDesiredAccess: DWORD,
|
||||
dwShareMode: DWORD,
|
||||
lpSecurityAttributes: LPSECURITY_ATTRIBUTES,
|
||||
dwCreationDisposition: DWORD,
|
||||
dwFlagsAndAttributes: DWORD,
|
||||
hTemplateFile: HANDLE) -> HANDLE;
|
||||
pub fn GetFinalPathNameByHandleW(hFile: HANDLE,
|
||||
lpszFilePath: LPCWSTR,
|
||||
cchFilePath: DWORD,
|
||||
dwFlags: DWORD) -> DWORD;
|
||||
pub fn ReadFile(hFile: HANDLE,
|
||||
lpBuffer: LPVOID,
|
||||
nNumberOfBytesToRead: DWORD,
|
||||
lpNumberOfBytesRead: LPDWORD,
|
||||
lpOverlapped: LPOVERLAPPED) -> BOOL;
|
||||
pub fn WriteFile(hFile: HANDLE,
|
||||
lpBuffer: LPVOID,
|
||||
nNumberOfBytesToRead: DWORD,
|
||||
lpNumberOfBytesRead: LPDWORD,
|
||||
lpOverlapped: LPOVERLAPPED) -> BOOL;
|
||||
pub fn SetFilePointerEx(hFile: HANDLE,
|
||||
liDistanceToMove: LARGE_INTEGER,
|
||||
lpNewFilePointer: PLARGE_INTEGER,
|
||||
dwMoveMethod: DWORD) -> BOOL;
|
||||
pub fn SetEndOfFile(hFile: HANDLE) -> BOOL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -110,62 +110,6 @@ rust_list_dir_wfd_fp_buf(void* wfd) {
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
rust_path_is_dir(const char *path) {
|
||||
struct stat buf;
|
||||
if (stat(path, &buf)) {
|
||||
return 0;
|
||||
}
|
||||
return S_ISDIR(buf.st_mode);
|
||||
}
|
||||
|
||||
int
|
||||
#if defined(__WIN32__)
|
||||
rust_path_is_dir_u16(const wchar_t *path) {
|
||||
struct _stat buf;
|
||||
// Don't use GetFileAttributesW, it cannot get attributes of
|
||||
// some system files (e.g. pagefile.sys).
|
||||
if (_wstat(path, &buf)) {
|
||||
return 0;
|
||||
}
|
||||
return S_ISDIR(buf.st_mode);
|
||||
}
|
||||
#else
|
||||
rust_path_is_dir_u16(const void *path) {
|
||||
// Wide version of function is only used on Windows.
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
rust_path_exists(const char *path) {
|
||||
struct stat buf;
|
||||
if (stat(path, &buf)) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
#if defined(__WIN32__)
|
||||
rust_path_exists_u16(const wchar_t *path) {
|
||||
struct _stat buf;
|
||||
if (_wstat(path, &buf)) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
#else
|
||||
rust_path_exists_u16(const void *path) {
|
||||
// Wide version of function is only used on Windows.
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
FILE* rust_get_stdin() {return stdin;}
|
||||
FILE* rust_get_stdout() {return stdout;}
|
||||
FILE* rust_get_stderr() {return stderr;}
|
||||
|
||||
#if defined(__WIN32__)
|
||||
void
|
||||
rust_get_time(int64_t *sec, int32_t *nsec) {
|
||||
|
@ -9,13 +9,6 @@ rust_localtime
|
||||
rust_timegm
|
||||
rust_mktime
|
||||
rust_precise_time_ns
|
||||
rust_path_is_dir
|
||||
rust_path_is_dir_u16
|
||||
rust_path_exists
|
||||
rust_path_exists_u16
|
||||
rust_get_stdin
|
||||
rust_get_stdout
|
||||
rust_get_stderr
|
||||
rust_list_dir_val
|
||||
rust_list_dir_wfd_size
|
||||
rust_list_dir_wfd_fp_buf
|
||||
|
@ -109,8 +109,8 @@ mod test_foreign_items {
|
||||
pub mod rustrt {
|
||||
extern {
|
||||
#[cfg(bogus)]
|
||||
pub fn rust_get_stdin() -> ~str;
|
||||
pub fn rust_get_stdin() -> ~str;
|
||||
pub fn write() -> ~str;
|
||||
pub fn write() -> ~str;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user