Remove rt::io::support
This removes the PathLike trait associated with this "support module". This is yet another "container of bytes" trait, so I didn't want to duplicate what already exists throughout libstd. In actuality, we're going to pass of C strings to the libuv APIs, so instead the arguments are now bound with the 'ToCStr' trait instead. Additionally, a layer of complexity was removed by immediately converting these type-generic parameters into CStrings to get handed off to libuv apis.
This commit is contained in:
parent
0cad984765
commit
9110a38cbf
@ -348,6 +348,34 @@ impl<'self> Iterator<libc::c_char> for CStringIterator<'self> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Parses a C "multistring", eg windows env values or
|
||||
/// the req->ptr result in a uv_fs_readdir() call.
|
||||
///
|
||||
/// Optionally, a `count` can be passed in, limiting the
|
||||
/// parsing to only being done `count`-times.
|
||||
///
|
||||
/// The specified closure is invoked with each string that
|
||||
/// is found, and the number of strings found is returned.
|
||||
pub unsafe fn from_c_multistring(buf: *libc::c_char,
|
||||
count: Option<uint>,
|
||||
f: &fn(&CString)) -> uint {
|
||||
|
||||
let mut curr_ptr: uint = buf as uint;
|
||||
let mut ctr = 0;
|
||||
let (limited_count, limit) = match count {
|
||||
Some(limit) => (true, limit),
|
||||
None => (false, 0)
|
||||
};
|
||||
while ((limited_count && ctr < limit) || !limited_count)
|
||||
&& *(curr_ptr as *libc::c_char) != 0 as libc::c_char {
|
||||
let cstr = CString::new(curr_ptr as *libc::c_char, false);
|
||||
f(&cstr);
|
||||
curr_ptr += cstr.len() + 1;
|
||||
ctr += 1;
|
||||
}
|
||||
return ctr;
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
@ -355,6 +383,21 @@ mod tests {
|
||||
use ptr;
|
||||
use option::{Some, None};
|
||||
|
||||
#[test]
|
||||
fn test_str_multistring_parsing() {
|
||||
unsafe {
|
||||
let input = bytes!("zero", "\x00", "one", "\x00", "\x00");
|
||||
let ptr = vec::raw::to_ptr(input);
|
||||
let expected = ["zero", "one"];
|
||||
let mut it = expected.iter();
|
||||
let result = do from_c_multistring(ptr as *libc::c_char, None) |c| {
|
||||
assert_eq!(c.as_str(), expected.next().unwrap());
|
||||
};
|
||||
assert_eq!(result, 2);
|
||||
assert!(it.next().is_none());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_str_to_c_str() {
|
||||
do "".to_c_str().with_ref |buf| {
|
||||
|
@ -62,7 +62,7 @@ pub fn close(fd: c_int) -> c_int {
|
||||
// which are for Windows and for non-Windows, if necessary.
|
||||
// See https://github.com/mozilla/rust/issues/9822 for more information.
|
||||
|
||||
pub mod rustrt {
|
||||
mod rustrt {
|
||||
use libc::{c_char, c_int};
|
||||
use libc;
|
||||
|
||||
@ -200,7 +200,10 @@ pub fn env() -> ~[(~str,~str)] {
|
||||
fail!("os::env() failure getting env string from OS: {}",
|
||||
os::last_os_error());
|
||||
}
|
||||
let result = str::raw::from_c_multistring(ch as *libc::c_char, None);
|
||||
let mut result = ~[];
|
||||
do c_str::from_c_multistring(ch as *libc::c_char, None) |cstr| {
|
||||
result.push(cstr.as_str().to_owned());
|
||||
};
|
||||
FreeEnvironmentStringsA(ch);
|
||||
result
|
||||
}
|
||||
|
@ -15,7 +15,8 @@ with regular files & directories on a filesystem.
|
||||
|
||||
At the top-level of the module are a set of freestanding functions,
|
||||
associated with various filesystem operations. They all operate
|
||||
on a `PathLike` object.
|
||||
on a `ToCStr` object. This trait is already defined for common
|
||||
objects such as strings and `Path` instances.
|
||||
|
||||
All operations in this module, including those as part of `FileStream` et al
|
||||
block the task during execution. Most will raise `std::rt::io::{io_error,read_error}`
|
||||
@ -30,7 +31,7 @@ free function counterparts.
|
||||
*/
|
||||
|
||||
use prelude::*;
|
||||
use super::support::PathLike;
|
||||
use c_str::ToCStr;
|
||||
use super::{Reader, Writer, Seek};
|
||||
use super::{SeekStyle, Read, Write};
|
||||
use rt::rtio::{RtioFileStream, IoFactory, IoFactoryObject};
|
||||
@ -48,7 +49,6 @@ use path::Path;
|
||||
///
|
||||
/// use std;
|
||||
/// use std::path::Path;
|
||||
/// use std::rt::io::support::PathLike;
|
||||
/// use std::rt::io::file::open;
|
||||
/// use std::rt::io::{FileMode, FileAccess};
|
||||
///
|
||||
@ -87,13 +87,13 @@ use path::Path;
|
||||
/// * Attempting to open a file with a `FileAccess` that the user lacks permissions
|
||||
/// for
|
||||
/// * Filesystem-level errors (full disk, etc)
|
||||
pub fn open<P: PathLike>(path: &P,
|
||||
mode: FileMode,
|
||||
access: FileAccess
|
||||
) -> Option<FileStream> {
|
||||
pub fn open<P: ToCStr>(path: &P,
|
||||
mode: FileMode,
|
||||
access: FileAccess
|
||||
) -> Option<FileStream> {
|
||||
let open_result = unsafe {
|
||||
let io: *mut IoFactoryObject = Local::unsafe_borrow();
|
||||
(*io).fs_open(path, mode, access)
|
||||
(*io).fs_open(&path.to_c_str(), mode, access)
|
||||
};
|
||||
match open_result {
|
||||
Ok(fd) => Some(FileStream {
|
||||
@ -113,7 +113,6 @@ pub fn open<P: PathLike>(path: &P,
|
||||
///
|
||||
/// use std;
|
||||
/// use std::path::Path;
|
||||
/// use std::rt::io::support::PathLike;
|
||||
/// use std::rt::io::file::unlink;
|
||||
///
|
||||
/// let p = &Path("/some/file/path.txt");
|
||||
@ -129,10 +128,10 @@ pub fn open<P: PathLike>(path: &P,
|
||||
///
|
||||
/// This function will raise an `io_error` condition if the user lacks permissions to
|
||||
/// remove the file or if some other filesystem-level error occurs
|
||||
pub fn unlink<P: PathLike>(path: &P) {
|
||||
pub fn unlink<P: ToCStr>(path: &P) {
|
||||
let unlink_result = unsafe {
|
||||
let io: *mut IoFactoryObject = Local::unsafe_borrow();
|
||||
(*io).fs_unlink(path)
|
||||
(*io).fs_unlink(&path.to_c_str())
|
||||
};
|
||||
match unlink_result {
|
||||
Ok(_) => (),
|
||||
@ -148,7 +147,6 @@ pub fn unlink<P: PathLike>(path: &P) {
|
||||
///
|
||||
/// use std;
|
||||
/// use std::path::Path;
|
||||
/// use std::rt::io::support::PathLike;
|
||||
/// use std::rt::io::file::mkdir;
|
||||
///
|
||||
/// let p = &Path("/some/dir");
|
||||
@ -159,10 +157,10 @@ pub fn unlink<P: PathLike>(path: &P) {
|
||||
///
|
||||
/// This call will raise an `io_error` condition if the user lacks permissions to make a
|
||||
/// new directory at the provided path, or if the directory already exists
|
||||
pub fn mkdir<P: PathLike>(path: &P) {
|
||||
pub fn mkdir<P: ToCStr>(path: &P) {
|
||||
let mkdir_result = unsafe {
|
||||
let io: *mut IoFactoryObject = Local::unsafe_borrow();
|
||||
(*io).fs_mkdir(path)
|
||||
(*io).fs_mkdir(&path.to_c_str())
|
||||
};
|
||||
match mkdir_result {
|
||||
Ok(_) => (),
|
||||
@ -178,7 +176,6 @@ pub fn mkdir<P: PathLike>(path: &P) {
|
||||
///
|
||||
/// use std;
|
||||
/// use std::path::Path;
|
||||
/// use std::rt::io::support::PathLike;
|
||||
/// use std::rt::io::file::rmdir;
|
||||
///
|
||||
/// let p = &Path("/some/dir");
|
||||
@ -189,10 +186,10 @@ pub fn mkdir<P: PathLike>(path: &P) {
|
||||
///
|
||||
/// This call will raise an `io_error` condition if the user lacks permissions to remove the
|
||||
/// directory at the provided path, or if the directory isn't empty
|
||||
pub fn rmdir<P: PathLike>(path: &P) {
|
||||
pub fn rmdir<P: ToCStr>(path: &P) {
|
||||
let rmdir_result = unsafe {
|
||||
let io: *mut IoFactoryObject = Local::unsafe_borrow();
|
||||
(*io).fs_rmdir(path)
|
||||
(*io).fs_rmdir(&path.to_c_str())
|
||||
};
|
||||
match rmdir_result {
|
||||
Ok(_) => (),
|
||||
@ -204,8 +201,8 @@ pub fn rmdir<P: PathLike>(path: &P) {
|
||||
|
||||
/// Get information on the file, directory, etc at the provided path
|
||||
///
|
||||
/// Given a `rt::io::support::PathLike`, query the file system to get
|
||||
/// information about a file, directory, etc.
|
||||
/// Given a path, query the file system to get information about a file,
|
||||
/// directory, etc.
|
||||
///
|
||||
/// Returns a `Some(std::rt::io::PathInfo)` on success
|
||||
///
|
||||
@ -213,7 +210,6 @@ pub fn rmdir<P: PathLike>(path: &P) {
|
||||
///
|
||||
/// use std;
|
||||
/// use std::path::Path;
|
||||
/// use std::rt::io::support::PathLike;
|
||||
/// use std::rt::io::file::stat;
|
||||
///
|
||||
/// let p = &Path("/some/file/path.txt");
|
||||
@ -238,10 +234,10 @@ pub fn rmdir<P: PathLike>(path: &P) {
|
||||
/// This call will raise an `io_error` condition if the user lacks the requisite
|
||||
/// permissions to perform a `stat` call on the given path or if there is no
|
||||
/// entry in the filesystem at the provided path.
|
||||
pub fn stat<P: PathLike>(path: &P) -> Option<FileStat> {
|
||||
pub fn stat<P: ToCStr>(path: &P) -> Option<FileStat> {
|
||||
let open_result = unsafe {
|
||||
let io: *mut IoFactoryObject = Local::unsafe_borrow();
|
||||
(*io).fs_stat(path)
|
||||
(*io).fs_stat(&path.to_c_str())
|
||||
};
|
||||
match open_result {
|
||||
Ok(p) => {
|
||||
@ -260,7 +256,6 @@ pub fn stat<P: PathLike>(path: &P) -> Option<FileStat> {
|
||||
///
|
||||
/// use std;
|
||||
/// use std::path::Path;
|
||||
/// use std::rt::io::support::PathLike;
|
||||
/// use std::rt::io::file::readdir;
|
||||
///
|
||||
/// fn visit_dirs(dir: &Path, cb: &fn(&Path)) {
|
||||
@ -279,10 +274,10 @@ pub fn stat<P: PathLike>(path: &P) -> Option<FileStat> {
|
||||
/// Will raise an `io_error` condition if the provided `path` doesn't exist,
|
||||
/// the process lacks permissions to view the contents or if the `path` points
|
||||
/// at a non-directory file
|
||||
pub fn readdir<P: PathLike>(path: &P) -> Option<~[Path]> {
|
||||
pub fn readdir<P: ToCStr>(path: &P) -> Option<~[Path]> {
|
||||
let readdir_result = unsafe {
|
||||
let io: *mut IoFactoryObject = Local::unsafe_borrow();
|
||||
(*io).fs_readdir(path, 0)
|
||||
(*io).fs_readdir(&path.to_c_str(), 0)
|
||||
};
|
||||
match readdir_result {
|
||||
Ok(p) => {
|
||||
|
@ -298,10 +298,6 @@ pub mod comm_adapters;
|
||||
/// Extension traits
|
||||
pub mod extensions;
|
||||
|
||||
/// Non-I/O things needed by the I/O module
|
||||
// XXX: shouldn this really be pub?
|
||||
pub mod support;
|
||||
|
||||
/// Basic Timer
|
||||
pub mod timer;
|
||||
|
||||
|
@ -24,7 +24,7 @@ instances as clients.
|
||||
|
||||
use prelude::*;
|
||||
|
||||
use super::super::support::PathLike;
|
||||
use c_str::ToCStr;
|
||||
use rt::rtio::{IoFactory, IoFactoryObject, RtioUnixListener};
|
||||
use rt::rtio::{RtioUnixAcceptor, RtioPipe, RtioUnixListenerObject};
|
||||
use rt::io::pipe::PipeStream;
|
||||
@ -59,7 +59,7 @@ impl UnixStream {
|
||||
/// let mut stream = UnixStream::connect(&server);
|
||||
/// stream.write([1, 2, 3]);
|
||||
///
|
||||
pub fn connect<P: PathLike>(path: &P) -> Option<UnixStream> {
|
||||
pub fn connect<P: ToCStr>(path: &P) -> Option<UnixStream> {
|
||||
let pipe = unsafe {
|
||||
let io: *mut IoFactoryObject = Local::unsafe_borrow();
|
||||
(*io).unix_connect(path)
|
||||
@ -112,7 +112,7 @@ impl UnixListener {
|
||||
/// client.write([1, 2, 3, 4]);
|
||||
/// }
|
||||
///
|
||||
pub fn bind<P: PathLike>(path: &P) -> Option<UnixListener> {
|
||||
pub fn bind<P: ToCStr>(path: &P) -> Option<UnixListener> {
|
||||
let listener = unsafe {
|
||||
let io: *mut IoFactoryObject = Local::unsafe_borrow();
|
||||
(*io).unix_bind(path)
|
||||
|
@ -1,42 +0,0 @@
|
||||
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use path::*;
|
||||
|
||||
pub trait PathLike {
|
||||
fn path_as_str<T>(&self, f: &fn(&str) -> T) -> T;
|
||||
}
|
||||
|
||||
impl<'self> PathLike for &'self str {
|
||||
fn path_as_str<T>(&self, f: &fn(&str) -> T) -> T {
|
||||
f(*self)
|
||||
}
|
||||
}
|
||||
|
||||
impl PathLike for Path {
|
||||
fn path_as_str<T>(&self, f: &fn(&str) -> T) -> T {
|
||||
let s = self.as_str().unwrap();
|
||||
f(s)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use path::*;
|
||||
use super::PathLike;
|
||||
|
||||
#[test]
|
||||
fn path_like_smoke_test() {
|
||||
let expected = if cfg!(unix) { "/home" } else { "C:\\" };
|
||||
let path = Path::new(expected);
|
||||
path.path_as_str(|p| assert!(p == expected));
|
||||
path.path_as_str(|p| assert!(p == expected));
|
||||
}
|
||||
}
|
@ -12,6 +12,7 @@ use libc;
|
||||
use option::*;
|
||||
use result::*;
|
||||
use libc::c_int;
|
||||
use c_str::CString;
|
||||
|
||||
use ai = rt::io::net::addrinfo;
|
||||
use rt::io::IoError;
|
||||
@ -19,7 +20,6 @@ use super::io::process::ProcessConfig;
|
||||
use super::io::net::ip::{IpAddr, SocketAddr};
|
||||
use rt::uv::uvio;
|
||||
use path::Path;
|
||||
use super::io::support::PathLike;
|
||||
use super::io::{SeekStyle};
|
||||
use super::io::{FileMode, FileAccess, FileStat};
|
||||
|
||||
@ -65,15 +65,14 @@ pub trait IoFactory {
|
||||
fn udp_bind(&mut self, addr: SocketAddr) -> Result<~RtioUdpSocket, IoError>;
|
||||
fn timer_init(&mut self) -> Result<~RtioTimer, IoError>;
|
||||
fn fs_from_raw_fd(&mut self, fd: c_int, close_on_drop: bool) -> ~RtioFileStream;
|
||||
fn fs_open<P: PathLike>(&mut self, path: &P, fm: FileMode, fa: FileAccess)
|
||||
fn fs_open(&mut self, path: &CString, fm: FileMode, fa: FileAccess)
|
||||
-> Result<~RtioFileStream, IoError>;
|
||||
fn fs_unlink<P: PathLike>(&mut self, path: &P) -> Result<(), IoError>;
|
||||
fn get_host_addresses(&mut self, host: Option<&str>, servname: Option<&str>,
|
||||
hint: Option<ai::Hint>) -> Result<~[ai::Info], IoError>;
|
||||
fn fs_stat<P: PathLike>(&mut self, path: &P) -> Result<FileStat, IoError>;
|
||||
fn fs_mkdir<P: PathLike>(&mut self, path: &P) -> Result<(), IoError>;
|
||||
fn fs_rmdir<P: PathLike>(&mut self, path: &P) -> Result<(), IoError>;
|
||||
fn fs_readdir<P: PathLike>(&mut self, path: &P, flags: c_int) ->
|
||||
fn fs_stat(&mut self, path: &CString) -> Result<FileStat, IoError>;
|
||||
fn fs_mkdir(&mut self, path: &CString) -> Result<(), IoError>;
|
||||
fn fs_rmdir(&mut self, path: &CString) -> Result<(), IoError>;
|
||||
fn fs_readdir(&mut self, path: &CString, flags: c_int) ->
|
||||
Result<~[Path], IoError>;
|
||||
fn spawn(&mut self, config: ProcessConfig)
|
||||
-> Result<(~RtioProcess, ~[Option<~RtioPipe>]), IoError>;
|
||||
|
@ -10,12 +10,13 @@
|
||||
|
||||
use prelude::*;
|
||||
use ptr::null;
|
||||
use c_str;
|
||||
use c_str::CString;
|
||||
use libc::c_void;
|
||||
use rt::uv::{Request, NativeHandle, Loop, FsCallback, Buf,
|
||||
status_to_maybe_uv_error, UvError};
|
||||
use rt::uv::uvll;
|
||||
use rt::uv::uvll::*;
|
||||
use super::super::io::support::PathLike;
|
||||
use cast::transmute;
|
||||
use libc;
|
||||
use libc::{c_int};
|
||||
@ -36,73 +37,63 @@ impl FsRequest {
|
||||
fs_req
|
||||
}
|
||||
|
||||
pub fn open<P: PathLike>(self, loop_: &Loop, path: &P, flags: int, mode: int,
|
||||
cb: FsCallback) {
|
||||
pub fn open(self, loop_: &Loop, path: &CString, flags: int, mode: int,
|
||||
cb: FsCallback) {
|
||||
let complete_cb_ptr = {
|
||||
let mut me = self;
|
||||
me.req_boilerplate(Some(cb))
|
||||
};
|
||||
path.path_as_str(|p| {
|
||||
p.with_c_str(|p| unsafe {
|
||||
path.with_ref(|p| unsafe {
|
||||
uvll::fs_open(loop_.native_handle(),
|
||||
self.native_handle(), p, flags, mode, complete_cb_ptr)
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
pub fn open_sync<P: PathLike>(self, loop_: &Loop, path: &P,
|
||||
flags: int, mode: int) -> Result<c_int, UvError> {
|
||||
pub fn open_sync(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 result = path.path_as_str(|p| {
|
||||
p.with_c_str(|p| unsafe {
|
||||
let result = path.with_ref(|p| unsafe {
|
||||
uvll::fs_open(loop_.native_handle(),
|
||||
self.native_handle(), p, flags, mode, complete_cb_ptr)
|
||||
})
|
||||
});
|
||||
self.sync_cleanup(result)
|
||||
}
|
||||
|
||||
pub fn unlink<P: PathLike>(self, loop_: &Loop, path: &P, cb: FsCallback) {
|
||||
pub fn unlink(self, loop_: &Loop, path: &CString, cb: FsCallback) {
|
||||
let complete_cb_ptr = {
|
||||
let mut me = self;
|
||||
me.req_boilerplate(Some(cb))
|
||||
};
|
||||
path.path_as_str(|p| {
|
||||
p.with_c_str(|p| unsafe {
|
||||
uvll::fs_unlink(loop_.native_handle(),
|
||||
self.native_handle(), p, complete_cb_ptr)
|
||||
})
|
||||
path.with_ref(|p| unsafe {
|
||||
uvll::fs_unlink(loop_.native_handle(),
|
||||
self.native_handle(), p, complete_cb_ptr)
|
||||
});
|
||||
}
|
||||
|
||||
pub fn unlink_sync<P: PathLike>(self, loop_: &Loop, path: &P)
|
||||
pub fn unlink_sync(self, loop_: &Loop, path: &CString)
|
||||
-> Result<c_int, UvError> {
|
||||
let complete_cb_ptr = {
|
||||
let mut me = self;
|
||||
me.req_boilerplate(None)
|
||||
};
|
||||
let result = path.path_as_str(|p| {
|
||||
p.with_c_str(|p| unsafe {
|
||||
uvll::fs_unlink(loop_.native_handle(),
|
||||
self.native_handle(), p, complete_cb_ptr)
|
||||
})
|
||||
let result = path.with_ref(|p| unsafe {
|
||||
uvll::fs_unlink(loop_.native_handle(),
|
||||
self.native_handle(), p, complete_cb_ptr)
|
||||
});
|
||||
self.sync_cleanup(result)
|
||||
}
|
||||
|
||||
pub fn stat<P: PathLike>(self, loop_: &Loop, path: &P, cb: FsCallback) {
|
||||
pub fn stat(self, loop_: &Loop, path: &CString, cb: FsCallback) {
|
||||
let complete_cb_ptr = {
|
||||
let mut me = self;
|
||||
me.req_boilerplate(Some(cb))
|
||||
};
|
||||
path.path_as_str(|p| {
|
||||
p.with_c_str(|p| unsafe {
|
||||
uvll::fs_stat(loop_.native_handle(),
|
||||
self.native_handle(), p, complete_cb_ptr)
|
||||
})
|
||||
path.with_ref(|p| unsafe {
|
||||
uvll::fs_stat(loop_.native_handle(),
|
||||
self.native_handle(), p, complete_cb_ptr)
|
||||
});
|
||||
}
|
||||
|
||||
@ -186,43 +177,37 @@ impl FsRequest {
|
||||
self.sync_cleanup(result)
|
||||
}
|
||||
|
||||
pub fn mkdir<P: PathLike>(self, loop_: &Loop, path: &P, mode: int, cb: FsCallback) {
|
||||
pub fn mkdir(self, loop_: &Loop, path: &CString, mode: int, cb: FsCallback) {
|
||||
let complete_cb_ptr = {
|
||||
let mut me = self;
|
||||
me.req_boilerplate(Some(cb))
|
||||
};
|
||||
path.path_as_str(|p| {
|
||||
p.with_c_str(|p| unsafe {
|
||||
path.with_ref(|p| unsafe {
|
||||
uvll::fs_mkdir(loop_.native_handle(),
|
||||
self.native_handle(), p, mode, complete_cb_ptr)
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
pub fn rmdir<P: PathLike>(self, loop_: &Loop, path: &P, cb: FsCallback) {
|
||||
pub fn rmdir(self, loop_: &Loop, path: &CString, cb: FsCallback) {
|
||||
let complete_cb_ptr = {
|
||||
let mut me = self;
|
||||
me.req_boilerplate(Some(cb))
|
||||
};
|
||||
path.path_as_str(|p| {
|
||||
p.with_c_str(|p| unsafe {
|
||||
path.with_ref(|p| unsafe {
|
||||
uvll::fs_rmdir(loop_.native_handle(),
|
||||
self.native_handle(), p, complete_cb_ptr)
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
pub fn readdir<P: PathLike>(self, loop_: &Loop, path: &P,
|
||||
flags: c_int, cb: FsCallback) {
|
||||
pub fn readdir(self, loop_: &Loop, path: &CString,
|
||||
flags: c_int, cb: FsCallback) {
|
||||
let complete_cb_ptr = {
|
||||
let mut me = self;
|
||||
me.req_boilerplate(Some(cb))
|
||||
};
|
||||
path.path_as_str(|p| {
|
||||
p.with_c_str(|p| unsafe {
|
||||
path.with_ref(|p| unsafe {
|
||||
uvll::fs_readdir(loop_.native_handle(),
|
||||
self.native_handle(), p, flags, complete_cb_ptr)
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
@ -286,13 +271,11 @@ impl FsRequest {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_paths(&mut self) -> ~[~str] {
|
||||
pub fn each_path(&mut self, f: &fn(&CString)) {
|
||||
use str;
|
||||
let ptr = self.get_ptr();
|
||||
match self.get_result() {
|
||||
n if (n <= 0) => {
|
||||
~[]
|
||||
},
|
||||
n if (n <= 0) => {}
|
||||
n => {
|
||||
let n_len = n as uint;
|
||||
// we pass in the len that uv tells us is there
|
||||
@ -301,11 +284,10 @@ impl FsRequest {
|
||||
// correctly delimited and we stray into garbage memory?
|
||||
// in any case, passing Some(n_len) fixes it and ensures
|
||||
// good results
|
||||
let raw_path_strs = unsafe {
|
||||
str::raw::from_c_multistring(ptr as *libc::c_char, Some(n_len)) };
|
||||
let raw_len = raw_path_strs.len();
|
||||
assert_eq!(raw_len, n_len);
|
||||
raw_path_strs
|
||||
unsafe {
|
||||
c_str::from_c_multistring(ptr as *libc::c_char,
|
||||
Some(n_len), f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use c_str::ToCStr;
|
||||
use c_str::{ToCStr, CString};
|
||||
use cast::transmute;
|
||||
use cast;
|
||||
use cell::Cell;
|
||||
@ -36,7 +36,6 @@ use rt::uv::net::{UvIpv4SocketAddr, UvIpv6SocketAddr};
|
||||
use rt::uv::addrinfo::{GetAddrInfoRequest, accum_addrinfo};
|
||||
use unstable::sync::Exclusive;
|
||||
use path::{GenericPath, Path};
|
||||
use super::super::io::support::PathLike;
|
||||
use libc::{lseek, off_t, O_CREAT, O_APPEND, O_TRUNC, O_RDWR, O_RDONLY, O_WRONLY,
|
||||
S_IRUSR, S_IWUSR, S_IRWXU};
|
||||
use rt::io::{FileMode, FileAccess, OpenOrCreate, Open, Create,
|
||||
@ -415,9 +414,9 @@ impl UvIoFactory {
|
||||
|
||||
/// Helper for a variety of simple uv_fs_* functions that
|
||||
/// have no ret val
|
||||
fn uv_fs_helper<P: PathLike>(loop_: &mut Loop, path: &P,
|
||||
cb: ~fn(&mut FsRequest, &mut Loop, &P,
|
||||
~fn(&FsRequest, Option<UvError>)))
|
||||
fn uv_fs_helper(loop_: &mut Loop, path: &CString,
|
||||
cb: ~fn(&mut FsRequest, &mut Loop, &CString,
|
||||
~fn(&FsRequest, Option<UvError>)))
|
||||
-> Result<(), IoError> {
|
||||
let result_cell = Cell::new_empty();
|
||||
let result_cell_ptr: *Cell<Result<(), IoError>> = &result_cell;
|
||||
@ -553,7 +552,7 @@ impl IoFactory for UvIoFactory {
|
||||
~UvFileStream::new(loop_, fd, close_on_drop, home) as ~RtioFileStream
|
||||
}
|
||||
|
||||
fn fs_open<P: PathLike>(&mut self, path: &P, fm: FileMode, fa: FileAccess)
|
||||
fn fs_open(&mut self, path: &CString, fm: FileMode, fa: FileAccess)
|
||||
-> Result<~RtioFileStream, IoError> {
|
||||
let mut flags = match fm {
|
||||
Open => 0,
|
||||
@ -608,14 +607,14 @@ impl IoFactory for UvIoFactory {
|
||||
return result_cell.take();
|
||||
}
|
||||
|
||||
fn fs_unlink<P: PathLike>(&mut self, path: &P) -> Result<(), IoError> {
|
||||
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<P: PathLike>(&mut self, path: &P) -> Result<FileStat, IoError> {
|
||||
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,
|
||||
@ -627,14 +626,13 @@ impl IoFactory for UvIoFactory {
|
||||
do scheduler.deschedule_running_task_and_then |_, task| {
|
||||
let task_cell = Cell::new(task);
|
||||
let path = path_cell.take();
|
||||
let path_str = path.path_as_str(|p| p.to_owned());
|
||||
do stat_req.stat(self.uv_loop(), path)
|
||||
|req,err| {
|
||||
let path_instance = Cell::new(Path::new(path.as_bytes()));
|
||||
do stat_req.stat(self.uv_loop(), path) |req,err| {
|
||||
let res = match err {
|
||||
None => {
|
||||
let stat = req.get_stat();
|
||||
Ok(FileStat {
|
||||
path: Path::new(path_str.as_slice()),
|
||||
path: path_instance.take(),
|
||||
is_file: stat.is_file(),
|
||||
is_dir: stat.is_dir(),
|
||||
device: stat.st_dev,
|
||||
@ -694,7 +692,7 @@ impl IoFactory for UvIoFactory {
|
||||
assert!(!result_cell.is_empty());
|
||||
return result_cell.take();
|
||||
}
|
||||
fn fs_mkdir<P: PathLike>(&mut self, path: &P) -> Result<(), IoError> {
|
||||
fn fs_mkdir(&mut self, path: &CString) -> Result<(), IoError> {
|
||||
let mode = S_IRWXU as int;
|
||||
do uv_fs_helper(self.uv_loop(), path) |mkdir_req, l, p, cb| {
|
||||
do mkdir_req.mkdir(l, p, mode as int) |req, err| {
|
||||
@ -702,14 +700,14 @@ impl IoFactory for UvIoFactory {
|
||||
};
|
||||
}
|
||||
}
|
||||
fn fs_rmdir<P: PathLike>(&mut self, path: &P) -> Result<(), IoError> {
|
||||
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)
|
||||
};
|
||||
}
|
||||
}
|
||||
fn fs_readdir<P: PathLike>(&mut self, path: &P, flags: c_int) ->
|
||||
fn fs_readdir(&mut self, path: &CString, flags: c_int) ->
|
||||
Result<~[Path], IoError> {
|
||||
use str::StrSlice;
|
||||
let result_cell = Cell::new_empty();
|
||||
@ -722,17 +720,14 @@ impl IoFactory for UvIoFactory {
|
||||
do scheduler.deschedule_running_task_and_then |_, task| {
|
||||
let task_cell = Cell::new(task);
|
||||
let path = path_cell.take();
|
||||
let path_str = path.path_as_str(|p| p.to_owned());
|
||||
do stat_req.readdir(self.uv_loop(), path, flags)
|
||||
|req,err| {
|
||||
let path_parent = Cell::new(Path::new(path.as_bytes()));
|
||||
do stat_req.readdir(self.uv_loop(), path, flags) |req,err| {
|
||||
let parent = path_parent.take();
|
||||
let res = match err {
|
||||
None => {
|
||||
let rel_paths = req.get_paths();
|
||||
let mut paths = ~[];
|
||||
for r in rel_paths.iter() {
|
||||
let mut p = Path::new(path_str.as_slice());
|
||||
p.push(r.as_slice());
|
||||
paths.push(p);
|
||||
do req.each_path |rel_path| {
|
||||
paths.push(parent.join(rel_path.as_bytes()));
|
||||
}
|
||||
Ok(paths)
|
||||
},
|
||||
@ -2417,20 +2412,20 @@ fn file_test_uvio_full_simple_impl() {
|
||||
{
|
||||
let create_fm = Create;
|
||||
let create_fa = ReadWrite;
|
||||
let mut fd = (*io).fs_open(&Path::new(path), create_fm, create_fa).unwrap();
|
||||
let mut fd = (*io).fs_open(&path.to_c_str(), create_fm, create_fa).unwrap();
|
||||
let write_buf = write_val.as_bytes();
|
||||
fd.write(write_buf);
|
||||
}
|
||||
{
|
||||
let ro_fm = Open;
|
||||
let ro_fa = Read;
|
||||
let mut fd = (*io).fs_open(&Path::new(path), ro_fm, ro_fa).unwrap();
|
||||
let mut fd = (*io).fs_open(&path.to_c_str(), ro_fm, ro_fa).unwrap();
|
||||
let mut read_vec = [0, .. 1028];
|
||||
let nread = fd.read(read_vec).unwrap();
|
||||
let read_val = str::from_utf8(read_vec.slice(0, nread as uint));
|
||||
assert!(read_val == write_val.to_owned());
|
||||
}
|
||||
(*io).fs_unlink(&Path::new(path));
|
||||
(*io).fs_unlink(&path.to_c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1172,34 +1172,6 @@ pub mod raw {
|
||||
vec::raw::set_len(as_owned_vec(s), new_len)
|
||||
}
|
||||
|
||||
/// Parses a C "multistring", eg windows env values or
|
||||
/// the req->ptr result in a uv_fs_readdir() call.
|
||||
/// Optionally, a `count` can be passed in, limiting the
|
||||
/// parsing to only being done `count`-times.
|
||||
#[inline]
|
||||
pub unsafe fn from_c_multistring(buf: *libc::c_char, count: Option<uint>) -> ~[~str] {
|
||||
#[fixed_stack_segment]; #[inline(never)];
|
||||
|
||||
let mut curr_ptr: uint = buf as uint;
|
||||
let mut result = ~[];
|
||||
let mut ctr = 0;
|
||||
let (limited_count, limit) = match count {
|
||||
Some(limit) => (true, limit),
|
||||
None => (false, 0)
|
||||
};
|
||||
while(((limited_count && ctr < limit) || !limited_count)
|
||||
&& *(curr_ptr as *libc::c_char) != 0 as libc::c_char) {
|
||||
let env_pair = from_c_str(
|
||||
curr_ptr as *libc::c_char);
|
||||
result.push(env_pair);
|
||||
curr_ptr +=
|
||||
libc::strlen(curr_ptr as *libc::c_char) as uint
|
||||
+ 1;
|
||||
ctr += 1;
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
/// Sets the length of a string
|
||||
///
|
||||
/// This will explicitly set the size of the string, without actually
|
||||
@ -1214,26 +1186,6 @@ pub mod raw {
|
||||
assert_eq!(c, ~"AAA");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_str_multistring_parsing() {
|
||||
use option::None;
|
||||
unsafe {
|
||||
let input = bytes!("zero", "\x00", "one", "\x00", "\x00");
|
||||
let ptr = vec::raw::to_ptr(input);
|
||||
let result = from_c_multistring(ptr as *libc::c_char, None);
|
||||
assert!(result.len() == 2);
|
||||
let mut ctr = 0;
|
||||
for x in result.iter() {
|
||||
match ctr {
|
||||
0 => assert_eq!(x, &~"zero"),
|
||||
1 => assert_eq!(x, &~"one"),
|
||||
_ => fail!("shouldn't happen!")
|
||||
}
|
||||
ctr += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
x
Reference in New Issue
Block a user