native: Deal with the rtio changes
This commit is contained in:
parent
da2293c6f6
commit
51348b068b
|
@ -8,21 +8,23 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use ai = std::io::net::addrinfo;
|
||||
use libc::{c_char, c_int};
|
||||
use libc;
|
||||
use std::c_str::CString;
|
||||
use std::io::IoError;
|
||||
use std::mem;
|
||||
use std::ptr::{null, mut_null};
|
||||
use std::rt::rtio;
|
||||
use std::rt::rtio::IoError;
|
||||
|
||||
use super::net::sockaddr_to_addr;
|
||||
use super::net;
|
||||
|
||||
pub struct GetAddrInfoRequest;
|
||||
|
||||
impl GetAddrInfoRequest {
|
||||
pub fn run(host: Option<&str>, servname: Option<&str>,
|
||||
hint: Option<ai::Hint>) -> Result<Vec<ai::Info>, IoError> {
|
||||
hint: Option<rtio::AddrinfoHint>)
|
||||
-> Result<Vec<rtio::AddrinfoInfo>, IoError>
|
||||
{
|
||||
assert!(host.is_some() || servname.is_some());
|
||||
|
||||
let c_host = host.map_or(unsafe { CString::new(null(), true) }, |x| x.to_c_str());
|
||||
|
@ -61,16 +63,16 @@ impl GetAddrInfoRequest {
|
|||
let mut rp = res;
|
||||
while rp.is_not_null() {
|
||||
unsafe {
|
||||
let addr = match sockaddr_to_addr(mem::transmute((*rp).ai_addr),
|
||||
(*rp).ai_addrlen as uint) {
|
||||
let addr = match net::sockaddr_to_addr(mem::transmute((*rp).ai_addr),
|
||||
(*rp).ai_addrlen as uint) {
|
||||
Ok(a) => a,
|
||||
Err(e) => return Err(e)
|
||||
};
|
||||
addrs.push(ai::Info {
|
||||
addrs.push(rtio::AddrinfoInfo {
|
||||
address: addr,
|
||||
family: (*rp).ai_family as uint,
|
||||
socktype: None,
|
||||
protocol: None,
|
||||
socktype: 0,
|
||||
protocol: 0,
|
||||
flags: (*rp).ai_flags as uint
|
||||
});
|
||||
|
||||
|
@ -96,21 +98,18 @@ extern "system" {
|
|||
|
||||
#[cfg(windows)]
|
||||
fn get_error(_: c_int) -> IoError {
|
||||
unsafe {
|
||||
IoError::from_errno(WSAGetLastError() as uint, true)
|
||||
}
|
||||
net::last_error()
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
fn get_error(s: c_int) -> IoError {
|
||||
use std::io;
|
||||
|
||||
let err_str = unsafe {
|
||||
CString::new(gai_strerror(s), false).as_str().unwrap().to_string()
|
||||
};
|
||||
IoError {
|
||||
kind: io::OtherIoError,
|
||||
desc: "unable to resolve host",
|
||||
code: s as uint,
|
||||
extra: 0,
|
||||
detail: Some(err_str),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,12 +14,12 @@ use alloc::arc::Arc;
|
|||
use libc::{c_int, c_void};
|
||||
use libc;
|
||||
use std::c_str::CString;
|
||||
use std::io::IoError;
|
||||
use std::io;
|
||||
use std::mem;
|
||||
use std::rt::rtio;
|
||||
use std::rt::rtio::IoResult;
|
||||
|
||||
use io::{IoResult, retry, keep_going};
|
||||
use io::{retry, keep_going};
|
||||
use io::util;
|
||||
|
||||
pub type fd_t = libc::c_int;
|
||||
|
||||
|
@ -51,21 +51,21 @@ impl FileDesc {
|
|||
// FIXME(#10465) these functions should not be public, but anything in
|
||||
// native::io wanting to use them is forced to have all the
|
||||
// rtio traits in scope
|
||||
pub fn inner_read(&mut self, buf: &mut [u8]) -> Result<uint, IoError> {
|
||||
pub fn inner_read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
|
||||
let ret = retry(|| unsafe {
|
||||
libc::read(self.fd(),
|
||||
buf.as_mut_ptr() as *mut libc::c_void,
|
||||
buf.len() as libc::size_t) as libc::c_int
|
||||
});
|
||||
if ret == 0 {
|
||||
Err(io::standard_error(io::EndOfFile))
|
||||
Err(util::eof())
|
||||
} else if ret < 0 {
|
||||
Err(super::last_error())
|
||||
} else {
|
||||
Ok(ret as uint)
|
||||
}
|
||||
}
|
||||
pub fn inner_write(&mut self, buf: &[u8]) -> Result<(), IoError> {
|
||||
pub fn inner_write(&mut self, buf: &[u8]) -> IoResult<()> {
|
||||
let ret = keep_going(buf, |buf, len| {
|
||||
unsafe {
|
||||
libc::write(self.fd(), buf as *libc::c_void,
|
||||
|
@ -82,26 +82,14 @@ impl FileDesc {
|
|||
pub fn fd(&self) -> fd_t { self.inner.fd }
|
||||
}
|
||||
|
||||
impl io::Reader for FileDesc {
|
||||
fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> {
|
||||
self.inner_read(buf)
|
||||
}
|
||||
}
|
||||
|
||||
impl io::Writer for FileDesc {
|
||||
fn write(&mut self, buf: &[u8]) -> io::IoResult<()> {
|
||||
self.inner_write(buf)
|
||||
}
|
||||
}
|
||||
|
||||
impl rtio::RtioFileStream for FileDesc {
|
||||
fn read(&mut self, buf: &mut [u8]) -> Result<int, IoError> {
|
||||
fn read(&mut self, buf: &mut [u8]) -> IoResult<int> {
|
||||
self.inner_read(buf).map(|i| i as int)
|
||||
}
|
||||
fn write(&mut self, buf: &[u8]) -> Result<(), IoError> {
|
||||
fn write(&mut self, buf: &[u8]) -> IoResult<()> {
|
||||
self.inner_write(buf)
|
||||
}
|
||||
fn pread(&mut self, buf: &mut [u8], offset: u64) -> Result<int, IoError> {
|
||||
fn pread(&mut self, buf: &mut [u8], offset: u64) -> IoResult<int> {
|
||||
match retry(|| unsafe {
|
||||
libc::pread(self.fd(), buf.as_ptr() as *libc::c_void,
|
||||
buf.len() as libc::size_t,
|
||||
|
@ -111,17 +99,17 @@ impl rtio::RtioFileStream for FileDesc {
|
|||
n => Ok(n as int)
|
||||
}
|
||||
}
|
||||
fn pwrite(&mut self, buf: &[u8], offset: u64) -> Result<(), IoError> {
|
||||
fn pwrite(&mut self, buf: &[u8], offset: u64) -> IoResult<()> {
|
||||
super::mkerr_libc(retry(|| unsafe {
|
||||
libc::pwrite(self.fd(), buf.as_ptr() as *libc::c_void,
|
||||
buf.len() as libc::size_t, offset as libc::off_t)
|
||||
} as c_int))
|
||||
}
|
||||
fn seek(&mut self, pos: i64, whence: io::SeekStyle) -> Result<u64, IoError> {
|
||||
fn seek(&mut self, pos: i64, whence: rtio::SeekStyle) -> IoResult<u64> {
|
||||
let whence = match whence {
|
||||
io::SeekSet => libc::SEEK_SET,
|
||||
io::SeekEnd => libc::SEEK_END,
|
||||
io::SeekCur => libc::SEEK_CUR,
|
||||
rtio::SeekSet => libc::SEEK_SET,
|
||||
rtio::SeekEnd => libc::SEEK_END,
|
||||
rtio::SeekCur => libc::SEEK_CUR,
|
||||
};
|
||||
let n = unsafe { libc::lseek(self.fd(), pos as libc::off_t, whence) };
|
||||
if n < 0 {
|
||||
|
@ -130,7 +118,7 @@ impl rtio::RtioFileStream for FileDesc {
|
|||
Ok(n as u64)
|
||||
}
|
||||
}
|
||||
fn tell(&self) -> Result<u64, IoError> {
|
||||
fn tell(&self) -> IoResult<u64> {
|
||||
let n = unsafe { libc::lseek(self.fd(), 0, libc::SEEK_CUR) };
|
||||
if n < 0 {
|
||||
Err(super::last_error())
|
||||
|
@ -138,10 +126,10 @@ impl rtio::RtioFileStream for FileDesc {
|
|||
Ok(n as u64)
|
||||
}
|
||||
}
|
||||
fn fsync(&mut self) -> Result<(), IoError> {
|
||||
fn fsync(&mut self) -> IoResult<()> {
|
||||
super::mkerr_libc(retry(|| unsafe { libc::fsync(self.fd()) }))
|
||||
}
|
||||
fn datasync(&mut self) -> Result<(), IoError> {
|
||||
fn datasync(&mut self) -> IoResult<()> {
|
||||
return super::mkerr_libc(os_datasync(self.fd()));
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
|
@ -157,13 +145,13 @@ impl rtio::RtioFileStream for FileDesc {
|
|||
retry(|| unsafe { libc::fsync(fd) })
|
||||
}
|
||||
}
|
||||
fn truncate(&mut self, offset: i64) -> Result<(), IoError> {
|
||||
fn truncate(&mut self, offset: i64) -> IoResult<()> {
|
||||
super::mkerr_libc(retry(|| unsafe {
|
||||
libc::ftruncate(self.fd(), offset as libc::off_t)
|
||||
}))
|
||||
}
|
||||
|
||||
fn fstat(&mut self) -> IoResult<io::FileStat> {
|
||||
fn fstat(&mut self) -> IoResult<rtio::FileStat> {
|
||||
let mut stat: libc::stat = unsafe { mem::zeroed() };
|
||||
match retry(|| unsafe { libc::fstat(self.fd(), &mut stat) }) {
|
||||
0 => Ok(mkstat(&stat)),
|
||||
|
@ -173,10 +161,10 @@ impl rtio::RtioFileStream for FileDesc {
|
|||
}
|
||||
|
||||
impl rtio::RtioPipe for FileDesc {
|
||||
fn read(&mut self, buf: &mut [u8]) -> Result<uint, IoError> {
|
||||
fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
|
||||
self.inner_read(buf)
|
||||
}
|
||||
fn write(&mut self, buf: &[u8]) -> Result<(), IoError> {
|
||||
fn write(&mut self, buf: &[u8]) -> IoResult<()> {
|
||||
self.inner_write(buf)
|
||||
}
|
||||
fn clone(&self) -> Box<rtio::RtioPipe:Send> {
|
||||
|
@ -187,11 +175,11 @@ impl rtio::RtioPipe for FileDesc {
|
|||
// impact on the std::io primitives, this is never called via
|
||||
// std::io::PipeStream. If the functionality is exposed in the future, then
|
||||
// these methods will need to be implemented.
|
||||
fn close_read(&mut self) -> Result<(), IoError> {
|
||||
Err(io::standard_error(io::InvalidInput))
|
||||
fn close_read(&mut self) -> IoResult<()> {
|
||||
Err(super::unimpl())
|
||||
}
|
||||
fn close_write(&mut self) -> Result<(), IoError> {
|
||||
Err(io::standard_error(io::InvalidInput))
|
||||
fn close_write(&mut self) -> IoResult<()> {
|
||||
Err(super::unimpl())
|
||||
}
|
||||
fn set_timeout(&mut self, _t: Option<u64>) {}
|
||||
fn set_read_timeout(&mut self, _t: Option<u64>) {}
|
||||
|
@ -199,16 +187,16 @@ impl rtio::RtioPipe for FileDesc {
|
|||
}
|
||||
|
||||
impl rtio::RtioTTY for FileDesc {
|
||||
fn read(&mut self, buf: &mut [u8]) -> Result<uint, IoError> {
|
||||
fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
|
||||
self.inner_read(buf)
|
||||
}
|
||||
fn write(&mut self, buf: &[u8]) -> Result<(), IoError> {
|
||||
fn write(&mut self, buf: &[u8]) -> IoResult<()> {
|
||||
self.inner_write(buf)
|
||||
}
|
||||
fn set_raw(&mut self, _raw: bool) -> Result<(), IoError> {
|
||||
fn set_raw(&mut self, _raw: bool) -> IoResult<()> {
|
||||
Err(super::unimpl())
|
||||
}
|
||||
fn get_winsize(&mut self) -> Result<(int, int), IoError> {
|
||||
fn get_winsize(&mut self) -> IoResult<(int, int)> {
|
||||
Err(super::unimpl())
|
||||
}
|
||||
fn isatty(&self) -> bool { false }
|
||||
|
@ -249,13 +237,13 @@ impl CFile {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn flush(&mut self) -> Result<(), IoError> {
|
||||
pub fn flush(&mut self) -> IoResult<()> {
|
||||
super::mkerr_libc(retry(|| unsafe { libc::fflush(self.file) }))
|
||||
}
|
||||
}
|
||||
|
||||
impl rtio::RtioFileStream for CFile {
|
||||
fn read(&mut self, buf: &mut [u8]) -> Result<int, IoError> {
|
||||
fn read(&mut self, buf: &mut [u8]) -> IoResult<int> {
|
||||
let ret = keep_going(buf, |buf, len| {
|
||||
unsafe {
|
||||
libc::fread(buf as *mut libc::c_void, 1, len as libc::size_t,
|
||||
|
@ -263,7 +251,7 @@ impl rtio::RtioFileStream for CFile {
|
|||
}
|
||||
});
|
||||
if ret == 0 {
|
||||
Err(io::standard_error(io::EndOfFile))
|
||||
Err(util::eof())
|
||||
} else if ret < 0 {
|
||||
Err(super::last_error())
|
||||
} else {
|
||||
|
@ -271,7 +259,7 @@ impl rtio::RtioFileStream for CFile {
|
|||
}
|
||||
}
|
||||
|
||||
fn write(&mut self, buf: &[u8]) -> Result<(), IoError> {
|
||||
fn write(&mut self, buf: &[u8]) -> IoResult<()> {
|
||||
let ret = keep_going(buf, |buf, len| {
|
||||
unsafe {
|
||||
libc::fwrite(buf as *libc::c_void, 1, len as libc::size_t,
|
||||
|
@ -285,17 +273,17 @@ impl rtio::RtioFileStream for CFile {
|
|||
}
|
||||
}
|
||||
|
||||
fn pread(&mut self, buf: &mut [u8], offset: u64) -> Result<int, IoError> {
|
||||
fn pread(&mut self, buf: &mut [u8], offset: u64) -> IoResult<int> {
|
||||
self.flush().and_then(|()| self.fd.pread(buf, offset))
|
||||
}
|
||||
fn pwrite(&mut self, buf: &[u8], offset: u64) -> Result<(), IoError> {
|
||||
fn pwrite(&mut self, buf: &[u8], offset: u64) -> IoResult<()> {
|
||||
self.flush().and_then(|()| self.fd.pwrite(buf, offset))
|
||||
}
|
||||
fn seek(&mut self, pos: i64, style: io::SeekStyle) -> Result<u64, IoError> {
|
||||
fn seek(&mut self, pos: i64, style: rtio::SeekStyle) -> IoResult<u64> {
|
||||
let whence = match style {
|
||||
io::SeekSet => libc::SEEK_SET,
|
||||
io::SeekEnd => libc::SEEK_END,
|
||||
io::SeekCur => libc::SEEK_CUR,
|
||||
rtio::SeekSet => libc::SEEK_SET,
|
||||
rtio::SeekEnd => libc::SEEK_END,
|
||||
rtio::SeekCur => libc::SEEK_CUR,
|
||||
};
|
||||
let n = unsafe { libc::fseek(self.file, pos as libc::c_long, whence) };
|
||||
if n < 0 {
|
||||
|
@ -304,7 +292,7 @@ impl rtio::RtioFileStream for CFile {
|
|||
Ok(n as u64)
|
||||
}
|
||||
}
|
||||
fn tell(&self) -> Result<u64, IoError> {
|
||||
fn tell(&self) -> IoResult<u64> {
|
||||
let ret = unsafe { libc::ftell(self.file) };
|
||||
if ret < 0 {
|
||||
Err(super::last_error())
|
||||
|
@ -312,17 +300,17 @@ impl rtio::RtioFileStream for CFile {
|
|||
Ok(ret as u64)
|
||||
}
|
||||
}
|
||||
fn fsync(&mut self) -> Result<(), IoError> {
|
||||
fn fsync(&mut self) -> IoResult<()> {
|
||||
self.flush().and_then(|()| self.fd.fsync())
|
||||
}
|
||||
fn datasync(&mut self) -> Result<(), IoError> {
|
||||
fn datasync(&mut self) -> IoResult<()> {
|
||||
self.flush().and_then(|()| self.fd.fsync())
|
||||
}
|
||||
fn truncate(&mut self, offset: i64) -> Result<(), IoError> {
|
||||
fn truncate(&mut self, offset: i64) -> IoResult<()> {
|
||||
self.flush().and_then(|()| self.fd.truncate(offset))
|
||||
}
|
||||
|
||||
fn fstat(&mut self) -> IoResult<io::FileStat> {
|
||||
fn fstat(&mut self) -> IoResult<rtio::FileStat> {
|
||||
self.flush().and_then(|()| self.fd.fstat())
|
||||
}
|
||||
}
|
||||
|
@ -333,20 +321,21 @@ impl Drop for CFile {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn open(path: &CString, fm: io::FileMode, fa: io::FileAccess)
|
||||
-> IoResult<FileDesc> {
|
||||
pub fn open(path: &CString, fm: rtio::FileMode, fa: rtio::FileAccess)
|
||||
-> IoResult<FileDesc>
|
||||
{
|
||||
let flags = match fm {
|
||||
io::Open => 0,
|
||||
io::Append => libc::O_APPEND,
|
||||
io::Truncate => libc::O_TRUNC,
|
||||
rtio::Open => 0,
|
||||
rtio::Append => libc::O_APPEND,
|
||||
rtio::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),
|
||||
rtio::Read => (flags | libc::O_RDONLY, 0),
|
||||
rtio::Write => (flags | libc::O_WRONLY | libc::O_CREAT,
|
||||
libc::S_IRUSR | libc::S_IWUSR),
|
||||
rtio::ReadWrite => (flags | libc::O_RDWR | libc::O_CREAT,
|
||||
libc::S_IRUSR | libc::S_IWUSR),
|
||||
};
|
||||
|
||||
match retry(|| unsafe { libc::open(path.with_ref(|p| p), flags, mode) }) {
|
||||
|
@ -355,9 +344,9 @@ pub fn open(path: &CString, fm: io::FileMode, fa: io::FileAccess)
|
|||
}
|
||||
}
|
||||
|
||||
pub fn mkdir(p: &CString, mode: io::FilePermission) -> IoResult<()> {
|
||||
pub fn mkdir(p: &CString, mode: uint) -> IoResult<()> {
|
||||
super::mkerr_libc(retry(|| unsafe {
|
||||
libc::mkdir(p.with_ref(|p| p), mode.bits() as libc::mode_t)
|
||||
libc::mkdir(p.with_ref(|p| p), mode as libc::mode_t)
|
||||
}))
|
||||
}
|
||||
|
||||
|
@ -412,9 +401,9 @@ pub fn rename(old: &CString, new: &CString) -> IoResult<()> {
|
|||
}))
|
||||
}
|
||||
|
||||
pub fn chmod(p: &CString, mode: io::FilePermission) -> IoResult<()> {
|
||||
pub fn chmod(p: &CString, mode: uint) -> IoResult<()> {
|
||||
super::mkerr_libc(retry(|| unsafe {
|
||||
libc::chmod(p.with_ref(|p| p), mode.bits() as libc::mode_t)
|
||||
libc::chmod(p.with_ref(|p| p), mode as libc::mode_t)
|
||||
}))
|
||||
}
|
||||
|
||||
|
@ -463,19 +452,10 @@ pub fn link(src: &CString, dst: &CString) -> IoResult<()> {
|
|||
}))
|
||||
}
|
||||
|
||||
fn mkstat(stat: &libc::stat) -> io::FileStat {
|
||||
fn mkstat(stat: &libc::stat) -> rtio::FileStat {
|
||||
// FileStat times are in milliseconds
|
||||
fn mktime(secs: u64, nsecs: u64) -> u64 { secs * 1000 + nsecs / 1000000 }
|
||||
|
||||
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,
|
||||
};
|
||||
|
||||
#[cfg(not(target_os = "linux"), not(target_os = "android"))]
|
||||
fn flags(stat: &libc::stat) -> u64 { stat.st_flags as u64 }
|
||||
#[cfg(target_os = "linux")] #[cfg(target_os = "android")]
|
||||
|
@ -486,29 +466,27 @@ fn mkstat(stat: &libc::stat) -> io::FileStat {
|
|||
#[cfg(target_os = "linux")] #[cfg(target_os = "android")]
|
||||
fn gen(_stat: &libc::stat) -> u64 { 0 }
|
||||
|
||||
io::FileStat {
|
||||
rtio::FileStat {
|
||||
size: stat.st_size as u64,
|
||||
kind: kind,
|
||||
perm: io::FilePermission::from_bits_truncate(stat.st_mode as u32),
|
||||
kind: stat.st_mode as u64,
|
||||
perm: stat.st_mode as u64,
|
||||
created: mktime(stat.st_ctime as u64, stat.st_ctime_nsec as u64),
|
||||
modified: mktime(stat.st_mtime as u64, stat.st_mtime_nsec as u64),
|
||||
accessed: mktime(stat.st_atime as u64, stat.st_atime_nsec as u64),
|
||||
unstable: io::UnstableFileStat {
|
||||
device: stat.st_dev as u64,
|
||||
inode: stat.st_ino as u64,
|
||||
rdev: stat.st_rdev as u64,
|
||||
nlink: stat.st_nlink as u64,
|
||||
uid: stat.st_uid as u64,
|
||||
gid: stat.st_gid as u64,
|
||||
blksize: stat.st_blksize as u64,
|
||||
blocks: stat.st_blocks as u64,
|
||||
flags: flags(stat),
|
||||
gen: gen(stat),
|
||||
}
|
||||
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: flags(stat),
|
||||
gen: gen(stat),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn stat(p: &CString) -> IoResult<io::FileStat> {
|
||||
pub fn stat(p: &CString) -> IoResult<rtio::FileStat> {
|
||||
let mut stat: libc::stat = unsafe { mem::zeroed() };
|
||||
match retry(|| unsafe { libc::stat(p.with_ref(|p| p), &mut stat) }) {
|
||||
0 => Ok(mkstat(&stat)),
|
||||
|
@ -516,7 +494,7 @@ pub fn stat(p: &CString) -> IoResult<io::FileStat> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn lstat(p: &CString) -> IoResult<io::FileStat> {
|
||||
pub fn lstat(p: &CString) -> IoResult<rtio::FileStat> {
|
||||
let mut stat: libc::stat = unsafe { mem::zeroed() };
|
||||
match retry(|| unsafe { libc::lstat(p.with_ref(|p| p), &mut stat) }) {
|
||||
0 => Ok(mkstat(&stat)),
|
||||
|
@ -537,10 +515,9 @@ pub fn utime(p: &CString, atime: u64, mtime: u64) -> IoResult<()> {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{CFile, FileDesc};
|
||||
use std::io;
|
||||
use libc;
|
||||
use std::os;
|
||||
use std::rt::rtio::RtioFileStream;
|
||||
use std::rt::rtio::{RtioFileStream, SeekSet};
|
||||
|
||||
#[ignore(cfg(target_os = "freebsd"))] // hmm, maybe pipes have a tiny buffer
|
||||
#[test]
|
||||
|
@ -551,7 +528,7 @@ mod tests {
|
|||
let mut reader = FileDesc::new(input, true);
|
||||
let mut writer = FileDesc::new(out, true);
|
||||
|
||||
writer.inner_write(bytes!("test")).unwrap();
|
||||
writer.inner_write(bytes!("test")).ok().unwrap();
|
||||
let mut buf = [0u8, ..4];
|
||||
match reader.inner_read(buf) {
|
||||
Ok(4) => {
|
||||
|
@ -574,9 +551,9 @@ mod tests {
|
|||
assert!(!f.is_null());
|
||||
let mut file = CFile::new(f);
|
||||
|
||||
file.write(bytes!("test")).unwrap();
|
||||
file.write(bytes!("test")).ok().unwrap();
|
||||
let mut buf = [0u8, ..4];
|
||||
let _ = file.seek(0, io::SeekSet).unwrap();
|
||||
let _ = file.seek(0, SeekSet).ok().unwrap();
|
||||
match file.read(buf) {
|
||||
Ok(4) => {
|
||||
assert_eq!(buf[0], 't' as u8);
|
||||
|
|
|
@ -24,9 +24,9 @@
|
|||
|
||||
use std::mem;
|
||||
use std::rt::bookkeeping;
|
||||
use std::rt::mutex::StaticNativeMutex;
|
||||
use std::rt;
|
||||
use std::ty::Unsafe;
|
||||
use std::unstable::mutex::StaticNativeMutex;
|
||||
|
||||
use task;
|
||||
|
||||
|
@ -57,7 +57,7 @@ pub struct Helper<M> {
|
|||
|
||||
macro_rules! helper_init( (static mut $name:ident: Helper<$m:ty>) => (
|
||||
static mut $name: Helper<$m> = Helper {
|
||||
lock: ::std::unstable::mutex::NATIVE_MUTEX_INIT,
|
||||
lock: ::std::rt::mutex::NATIVE_MUTEX_INIT,
|
||||
chan: ::std::ty::Unsafe {
|
||||
value: 0 as *mut Sender<$m>,
|
||||
marker1: ::std::kinds::marker::InvariantType,
|
||||
|
@ -163,7 +163,7 @@ mod imp {
|
|||
}
|
||||
|
||||
pub fn signal(fd: libc::c_int) {
|
||||
FileDesc::new(fd, false).inner_write([0]).unwrap();
|
||||
FileDesc::new(fd, false).inner_write([0]).ok().unwrap();
|
||||
}
|
||||
|
||||
pub fn close(fd: libc::c_int) {
|
||||
|
|
|
@ -26,16 +26,9 @@
|
|||
use libc::c_int;
|
||||
use libc;
|
||||
use std::c_str::CString;
|
||||
use std::io;
|
||||
use std::io::IoError;
|
||||
use std::io::net::ip::SocketAddr;
|
||||
use std::io::signal::Signum;
|
||||
use std::os;
|
||||
use std::rt::rtio;
|
||||
use std::rt::rtio::{RtioTcpStream, RtioTcpListener, RtioUdpSocket};
|
||||
use std::rt::rtio::{RtioUnixListener, RtioPipe, RtioFileStream, RtioProcess};
|
||||
use std::rt::rtio::{RtioSignal, RtioTTY, CloseBehavior, RtioTimer, ProcessConfig};
|
||||
use ai = std::io::net::addrinfo;
|
||||
use std::rt::rtio::{IoResult, IoError};
|
||||
|
||||
// Local re-exports
|
||||
pub use self::file::FileDesc;
|
||||
|
@ -78,18 +71,23 @@ pub mod pipe;
|
|||
#[cfg(unix)] #[path = "c_unix.rs"] mod c;
|
||||
#[cfg(windows)] #[path = "c_win32.rs"] mod c;
|
||||
|
||||
pub type IoResult<T> = Result<T, IoError>;
|
||||
|
||||
fn unimpl() -> IoError {
|
||||
#[cfg(unix)] use ERROR = libc::ENOSYS;
|
||||
#[cfg(windows)] use ERROR = libc::ERROR_CALL_NOT_IMPLEMENTED;
|
||||
IoError {
|
||||
kind: io::IoUnavailable,
|
||||
desc: "unimplemented I/O interface",
|
||||
code: ERROR as uint,
|
||||
extra: 0,
|
||||
detail: None,
|
||||
}
|
||||
}
|
||||
|
||||
fn last_error() -> IoError {
|
||||
IoError::last_error()
|
||||
let errno = os::errno() as uint;
|
||||
IoError {
|
||||
code: os::errno() as uint,
|
||||
extra: 0,
|
||||
detail: Some(os::error_string(errno)),
|
||||
}
|
||||
}
|
||||
|
||||
// unix has nonzero values as errors
|
||||
|
@ -166,64 +164,70 @@ impl IoFactory {
|
|||
|
||||
impl rtio::IoFactory for IoFactory {
|
||||
// networking
|
||||
fn tcp_connect(&mut self, addr: SocketAddr,
|
||||
timeout: Option<u64>) -> IoResult<Box<RtioTcpStream:Send>> {
|
||||
fn tcp_connect(&mut self, addr: rtio::SocketAddr,
|
||||
timeout: Option<u64>)
|
||||
-> IoResult<Box<rtio::RtioTcpStream:Send>>
|
||||
{
|
||||
net::TcpStream::connect(addr, timeout).map(|s| {
|
||||
box s as Box<RtioTcpStream:Send>
|
||||
box s as Box<rtio::RtioTcpStream:Send>
|
||||
})
|
||||
}
|
||||
fn tcp_bind(&mut self, addr: SocketAddr)
|
||||
-> IoResult<Box<RtioTcpListener:Send>> {
|
||||
fn tcp_bind(&mut self, addr: rtio::SocketAddr)
|
||||
-> IoResult<Box<rtio::RtioTcpListener:Send>> {
|
||||
net::TcpListener::bind(addr).map(|s| {
|
||||
box s as Box<RtioTcpListener:Send>
|
||||
box s as Box<rtio::RtioTcpListener:Send>
|
||||
})
|
||||
}
|
||||
fn udp_bind(&mut self, addr: SocketAddr)
|
||||
-> IoResult<Box<RtioUdpSocket:Send>> {
|
||||
net::UdpSocket::bind(addr).map(|u| box u as Box<RtioUdpSocket:Send>)
|
||||
fn udp_bind(&mut self, addr: rtio::SocketAddr)
|
||||
-> IoResult<Box<rtio::RtioUdpSocket:Send>> {
|
||||
net::UdpSocket::bind(addr).map(|u| {
|
||||
box u as Box<rtio::RtioUdpSocket:Send>
|
||||
})
|
||||
}
|
||||
fn unix_bind(&mut self, path: &CString)
|
||||
-> IoResult<Box<RtioUnixListener:Send>> {
|
||||
-> IoResult<Box<rtio::RtioUnixListener:Send>> {
|
||||
pipe::UnixListener::bind(path).map(|s| {
|
||||
box s as Box<RtioUnixListener:Send>
|
||||
box s as Box<rtio::RtioUnixListener:Send>
|
||||
})
|
||||
}
|
||||
fn unix_connect(&mut self, path: &CString,
|
||||
timeout: Option<u64>) -> IoResult<Box<RtioPipe:Send>> {
|
||||
timeout: Option<u64>) -> IoResult<Box<rtio::RtioPipe:Send>> {
|
||||
pipe::UnixStream::connect(path, timeout).map(|s| {
|
||||
box s as Box<RtioPipe:Send>
|
||||
box s as Box<rtio::RtioPipe:Send>
|
||||
})
|
||||
}
|
||||
fn get_host_addresses(&mut self, host: Option<&str>, servname: Option<&str>,
|
||||
hint: Option<ai::Hint>) -> IoResult<Vec<ai::Info>> {
|
||||
hint: Option<rtio::AddrinfoHint>)
|
||||
-> IoResult<Vec<rtio::AddrinfoInfo>>
|
||||
{
|
||||
addrinfo::GetAddrInfoRequest::run(host, servname, hint)
|
||||
}
|
||||
|
||||
// filesystem operations
|
||||
fn fs_from_raw_fd(&mut self, fd: c_int, close: CloseBehavior)
|
||||
-> Box<RtioFileStream:Send> {
|
||||
fn fs_from_raw_fd(&mut self, fd: c_int, close: rtio::CloseBehavior)
|
||||
-> Box<rtio::RtioFileStream:Send> {
|
||||
let close = match close {
|
||||
rtio::CloseSynchronously | rtio::CloseAsynchronously => true,
|
||||
rtio::DontClose => false
|
||||
};
|
||||
box file::FileDesc::new(fd, close) as Box<RtioFileStream:Send>
|
||||
box file::FileDesc::new(fd, close) as Box<rtio::RtioFileStream:Send>
|
||||
}
|
||||
fn fs_open(&mut self, path: &CString, fm: io::FileMode, fa: io::FileAccess)
|
||||
-> IoResult<Box<RtioFileStream:Send>> {
|
||||
file::open(path, fm, fa).map(|fd| box fd as Box<RtioFileStream:Send>)
|
||||
fn fs_open(&mut self, path: &CString, fm: rtio::FileMode,
|
||||
fa: rtio::FileAccess)
|
||||
-> IoResult<Box<rtio::RtioFileStream:Send>>
|
||||
{
|
||||
file::open(path, fm, fa).map(|fd| box fd as Box<rtio::RtioFileStream:Send>)
|
||||
}
|
||||
fn fs_unlink(&mut self, path: &CString) -> IoResult<()> {
|
||||
file::unlink(path)
|
||||
}
|
||||
fn fs_stat(&mut self, path: &CString) -> IoResult<io::FileStat> {
|
||||
fn fs_stat(&mut self, path: &CString) -> IoResult<rtio::FileStat> {
|
||||
file::stat(path)
|
||||
}
|
||||
fn fs_mkdir(&mut self, path: &CString,
|
||||
mode: io::FilePermission) -> IoResult<()> {
|
||||
fn fs_mkdir(&mut self, path: &CString, mode: uint) -> IoResult<()> {
|
||||
file::mkdir(path, mode)
|
||||
}
|
||||
fn fs_chmod(&mut self, path: &CString,
|
||||
mode: io::FilePermission) -> IoResult<()> {
|
||||
fn fs_chmod(&mut self, path: &CString, mode: uint) -> IoResult<()> {
|
||||
file::chmod(path, mode)
|
||||
}
|
||||
fn fs_rmdir(&mut self, path: &CString) -> IoResult<()> {
|
||||
|
@ -235,7 +239,7 @@ impl rtio::IoFactory for IoFactory {
|
|||
fn fs_readdir(&mut self, path: &CString, _flags: c_int) -> IoResult<Vec<CString>> {
|
||||
file::readdir(path)
|
||||
}
|
||||
fn fs_lstat(&mut self, path: &CString) -> IoResult<io::FileStat> {
|
||||
fn fs_lstat(&mut self, path: &CString) -> IoResult<rtio::FileStat> {
|
||||
file::lstat(path)
|
||||
}
|
||||
fn fs_chown(&mut self, path: &CString, uid: int, gid: int) -> IoResult<()> {
|
||||
|
@ -256,39 +260,41 @@ impl rtio::IoFactory for IoFactory {
|
|||
}
|
||||
|
||||
// misc
|
||||
fn timer_init(&mut self) -> IoResult<Box<RtioTimer:Send>> {
|
||||
timer::Timer::new().map(|t| box t as Box<RtioTimer:Send>)
|
||||
fn timer_init(&mut self) -> IoResult<Box<rtio::RtioTimer:Send>> {
|
||||
timer::Timer::new().map(|t| box t as Box<rtio::RtioTimer:Send>)
|
||||
}
|
||||
fn spawn(&mut self, cfg: ProcessConfig)
|
||||
-> IoResult<(Box<RtioProcess:Send>,
|
||||
Vec<Option<Box<RtioPipe:Send>>>)> {
|
||||
fn spawn(&mut self, cfg: rtio::ProcessConfig)
|
||||
-> IoResult<(Box<rtio::RtioProcess:Send>,
|
||||
Vec<Option<Box<rtio::RtioPipe:Send>>>)> {
|
||||
process::Process::spawn(cfg).map(|(p, io)| {
|
||||
(box p as Box<RtioProcess:Send>,
|
||||
(box p as Box<rtio::RtioProcess:Send>,
|
||||
io.move_iter().map(|p| p.map(|p| {
|
||||
box p as Box<RtioPipe:Send>
|
||||
box p as Box<rtio::RtioPipe:Send>
|
||||
})).collect())
|
||||
})
|
||||
}
|
||||
fn kill(&mut self, pid: libc::pid_t, signum: int) -> IoResult<()> {
|
||||
process::Process::kill(pid, signum)
|
||||
}
|
||||
fn pipe_open(&mut self, fd: c_int) -> IoResult<Box<RtioPipe:Send>> {
|
||||
Ok(box file::FileDesc::new(fd, true) as Box<RtioPipe:Send>)
|
||||
fn pipe_open(&mut self, fd: c_int) -> IoResult<Box<rtio::RtioPipe:Send>> {
|
||||
Ok(box file::FileDesc::new(fd, true) as Box<rtio::RtioPipe:Send>)
|
||||
}
|
||||
fn tty_open(&mut self, fd: c_int, _readable: bool)
|
||||
-> IoResult<Box<RtioTTY:Send>> {
|
||||
-> IoResult<Box<rtio::RtioTTY:Send>> {
|
||||
#[cfg(unix)] use ERROR = libc::ENOTTY;
|
||||
#[cfg(windows)] use ERROR = libc::ERROR_INVALID_HANDLE;
|
||||
if unsafe { libc::isatty(fd) } != 0 {
|
||||
Ok(box file::FileDesc::new(fd, true) as Box<RtioTTY:Send>)
|
||||
Ok(box file::FileDesc::new(fd, true) as Box<rtio::RtioTTY:Send>)
|
||||
} else {
|
||||
Err(IoError {
|
||||
kind: io::MismatchedFileTypeForOperation,
|
||||
desc: "file descriptor is not a TTY",
|
||||
code: ERROR as uint,
|
||||
extra: 0,
|
||||
detail: None,
|
||||
})
|
||||
}
|
||||
}
|
||||
fn signal(&mut self, _signal: Signum, _channel: Sender<Signum>)
|
||||
-> IoResult<Box<RtioSignal:Send>> {
|
||||
fn signal(&mut self, _signal: int, _cb: Box<rtio::Callback>)
|
||||
-> IoResult<Box<rtio::RtioSignal:Send>> {
|
||||
Err(unimpl())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,13 +10,12 @@
|
|||
|
||||
use alloc::arc::Arc;
|
||||
use libc;
|
||||
use std::io::net::ip;
|
||||
use std::io;
|
||||
use std::mem;
|
||||
use std::rt::mutex;
|
||||
use std::rt::rtio;
|
||||
use std::unstable::mutex;
|
||||
use std::rt::rtio::{IoResult, IoError};
|
||||
|
||||
use super::{IoResult, retry, keep_going};
|
||||
use super::{retry, keep_going};
|
||||
use super::c;
|
||||
use super::util;
|
||||
|
||||
|
@ -39,9 +38,9 @@ enum InAddr {
|
|||
In6Addr(libc::in6_addr),
|
||||
}
|
||||
|
||||
fn ip_to_inaddr(ip: ip::IpAddr) -> InAddr {
|
||||
fn ip_to_inaddr(ip: rtio::IpAddr) -> InAddr {
|
||||
match ip {
|
||||
ip::Ipv4Addr(a, b, c, d) => {
|
||||
rtio::Ipv4Addr(a, b, c, d) => {
|
||||
let ip = (a as u32 << 24) |
|
||||
(b as u32 << 16) |
|
||||
(c as u32 << 8) |
|
||||
|
@ -50,7 +49,7 @@ fn ip_to_inaddr(ip: ip::IpAddr) -> InAddr {
|
|||
s_addr: mem::from_be32(ip)
|
||||
})
|
||||
}
|
||||
ip::Ipv6Addr(a, b, c, d, e, f, g, h) => {
|
||||
rtio::Ipv6Addr(a, b, c, d, e, f, g, h) => {
|
||||
In6Addr(libc::in6_addr {
|
||||
s6_addr: [
|
||||
htons(a),
|
||||
|
@ -67,7 +66,7 @@ fn ip_to_inaddr(ip: ip::IpAddr) -> InAddr {
|
|||
}
|
||||
}
|
||||
|
||||
fn addr_to_sockaddr(addr: ip::SocketAddr) -> (libc::sockaddr_storage, uint) {
|
||||
fn addr_to_sockaddr(addr: rtio::SocketAddr) -> (libc::sockaddr_storage, uint) {
|
||||
unsafe {
|
||||
let storage: libc::sockaddr_storage = mem::zeroed();
|
||||
let len = match ip_to_inaddr(addr.ip) {
|
||||
|
@ -90,11 +89,11 @@ fn addr_to_sockaddr(addr: ip::SocketAddr) -> (libc::sockaddr_storage, uint) {
|
|||
}
|
||||
}
|
||||
|
||||
fn socket(addr: ip::SocketAddr, ty: libc::c_int) -> IoResult<sock_t> {
|
||||
fn socket(addr: rtio::SocketAddr, ty: libc::c_int) -> IoResult<sock_t> {
|
||||
unsafe {
|
||||
let fam = match addr.ip {
|
||||
ip::Ipv4Addr(..) => libc::AF_INET,
|
||||
ip::Ipv6Addr(..) => libc::AF_INET6,
|
||||
rtio::Ipv4Addr(..) => libc::AF_INET,
|
||||
rtio::Ipv6Addr(..) => libc::AF_INET6,
|
||||
};
|
||||
match libc::socket(fam, ty, 0) {
|
||||
-1 => Err(super::last_error()),
|
||||
|
@ -136,12 +135,16 @@ pub fn getsockopt<T: Copy>(fd: sock_t, opt: libc::c_int,
|
|||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn last_error() -> io::IoError {
|
||||
io::IoError::from_errno(unsafe { c::WSAGetLastError() } as uint, true)
|
||||
fn last_error() -> IoError {
|
||||
let code = unsafe { c::WSAGetLastError() as uint };
|
||||
IoError {
|
||||
code: code,
|
||||
detail: Some(os::error_string(code)),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
fn last_error() -> io::IoError {
|
||||
fn last_error() -> IoError {
|
||||
super::last_error()
|
||||
}
|
||||
|
||||
|
@ -151,7 +154,7 @@ fn last_error() -> io::IoError {
|
|||
fn sockname(fd: sock_t,
|
||||
f: unsafe extern "system" fn(sock_t, *mut libc::sockaddr,
|
||||
*mut libc::socklen_t) -> libc::c_int)
|
||||
-> IoResult<ip::SocketAddr>
|
||||
-> IoResult<rtio::SocketAddr>
|
||||
{
|
||||
let mut storage: libc::sockaddr_storage = unsafe { mem::zeroed() };
|
||||
let mut len = mem::size_of::<libc::sockaddr_storage>() as libc::socklen_t;
|
||||
|
@ -168,7 +171,7 @@ fn sockname(fd: sock_t,
|
|||
}
|
||||
|
||||
pub fn sockaddr_to_addr(storage: &libc::sockaddr_storage,
|
||||
len: uint) -> IoResult<ip::SocketAddr> {
|
||||
len: uint) -> IoResult<rtio::SocketAddr> {
|
||||
match storage.ss_family as libc::c_int {
|
||||
libc::AF_INET => {
|
||||
assert!(len as uint >= mem::size_of::<libc::sockaddr_in>());
|
||||
|
@ -180,8 +183,8 @@ pub fn sockaddr_to_addr(storage: &libc::sockaddr_storage,
|
|||
let b = (ip >> 16) as u8;
|
||||
let c = (ip >> 8) as u8;
|
||||
let d = (ip >> 0) as u8;
|
||||
Ok(ip::SocketAddr {
|
||||
ip: ip::Ipv4Addr(a, b, c, d),
|
||||
Ok(rtio::SocketAddr {
|
||||
ip: rtio::Ipv4Addr(a, b, c, d),
|
||||
port: ntohs(storage.sin_port),
|
||||
})
|
||||
}
|
||||
|
@ -198,13 +201,19 @@ pub fn sockaddr_to_addr(storage: &libc::sockaddr_storage,
|
|||
let f = ntohs(storage.sin6_addr.s6_addr[5]);
|
||||
let g = ntohs(storage.sin6_addr.s6_addr[6]);
|
||||
let h = ntohs(storage.sin6_addr.s6_addr[7]);
|
||||
Ok(ip::SocketAddr {
|
||||
ip: ip::Ipv6Addr(a, b, c, d, e, f, g, h),
|
||||
Ok(rtio::SocketAddr {
|
||||
ip: rtio::Ipv6Addr(a, b, c, d, e, f, g, h),
|
||||
port: ntohs(storage.sin6_port),
|
||||
})
|
||||
}
|
||||
_ => {
|
||||
Err(io::standard_error(io::OtherIoError))
|
||||
#[cfg(unix)] use ERROR = libc::EINVAL;
|
||||
#[cfg(windows)] use ERROR = libc::WSAEINVAL;
|
||||
Err(IoError {
|
||||
code: ERROR as uint,
|
||||
extra: 0,
|
||||
detail: None,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -258,7 +267,7 @@ impl Inner {
|
|||
}
|
||||
|
||||
impl TcpStream {
|
||||
pub fn connect(addr: ip::SocketAddr,
|
||||
pub fn connect(addr: rtio::SocketAddr,
|
||||
timeout: Option<u64>) -> IoResult<TcpStream> {
|
||||
let fd = try!(socket(addr, libc::SOCK_STREAM));
|
||||
let ret = TcpStream::new(Inner::new(fd));
|
||||
|
@ -366,7 +375,7 @@ impl rtio::RtioTcpStream for TcpStream {
|
|||
Err(e) => Err(e)
|
||||
}
|
||||
}
|
||||
fn peer_name(&mut self) -> IoResult<ip::SocketAddr> {
|
||||
fn peer_name(&mut self) -> IoResult<rtio::SocketAddr> {
|
||||
sockname(self.fd(), libc::getpeername)
|
||||
}
|
||||
fn control_congestion(&mut self) -> IoResult<()> {
|
||||
|
@ -411,7 +420,7 @@ impl rtio::RtioTcpStream for TcpStream {
|
|||
}
|
||||
|
||||
impl rtio::RtioSocket for TcpStream {
|
||||
fn socket_name(&mut self) -> IoResult<ip::SocketAddr> {
|
||||
fn socket_name(&mut self) -> IoResult<rtio::SocketAddr> {
|
||||
sockname(self.fd(), libc::getsockname)
|
||||
}
|
||||
}
|
||||
|
@ -436,7 +445,7 @@ pub struct TcpListener {
|
|||
}
|
||||
|
||||
impl TcpListener {
|
||||
pub fn bind(addr: ip::SocketAddr) -> IoResult<TcpListener> {
|
||||
pub fn bind(addr: rtio::SocketAddr) -> IoResult<TcpListener> {
|
||||
let fd = try!(socket(addr, libc::SOCK_STREAM));
|
||||
let ret = TcpListener { inner: Inner::new(fd) };
|
||||
|
||||
|
@ -477,7 +486,7 @@ impl rtio::RtioTcpListener for TcpListener {
|
|||
}
|
||||
|
||||
impl rtio::RtioSocket for TcpListener {
|
||||
fn socket_name(&mut self) -> IoResult<ip::SocketAddr> {
|
||||
fn socket_name(&mut self) -> IoResult<rtio::SocketAddr> {
|
||||
sockname(self.fd(), libc::getsockname)
|
||||
}
|
||||
}
|
||||
|
@ -512,7 +521,7 @@ impl TcpAcceptor {
|
|||
}
|
||||
|
||||
impl rtio::RtioSocket for TcpAcceptor {
|
||||
fn socket_name(&mut self) -> IoResult<ip::SocketAddr> {
|
||||
fn socket_name(&mut self) -> IoResult<rtio::SocketAddr> {
|
||||
sockname(self.fd(), libc::getsockname)
|
||||
}
|
||||
}
|
||||
|
@ -540,7 +549,7 @@ pub struct UdpSocket {
|
|||
}
|
||||
|
||||
impl UdpSocket {
|
||||
pub fn bind(addr: ip::SocketAddr) -> IoResult<UdpSocket> {
|
||||
pub fn bind(addr: rtio::SocketAddr) -> IoResult<UdpSocket> {
|
||||
let fd = try!(socket(addr, libc::SOCK_DGRAM));
|
||||
let ret = UdpSocket {
|
||||
inner: Arc::new(Inner::new(fd)),
|
||||
|
@ -570,7 +579,7 @@ impl UdpSocket {
|
|||
on as libc::c_int)
|
||||
}
|
||||
|
||||
pub fn set_membership(&mut self, addr: ip::IpAddr,
|
||||
pub fn set_membership(&mut self, addr: rtio::IpAddr,
|
||||
opt: libc::c_int) -> IoResult<()> {
|
||||
match ip_to_inaddr(addr) {
|
||||
InAddr(addr) => {
|
||||
|
@ -606,7 +615,7 @@ impl UdpSocket {
|
|||
}
|
||||
|
||||
impl rtio::RtioSocket for UdpSocket {
|
||||
fn socket_name(&mut self) -> IoResult<ip::SocketAddr> {
|
||||
fn socket_name(&mut self) -> IoResult<rtio::SocketAddr> {
|
||||
sockname(self.fd(), libc::getsockname)
|
||||
}
|
||||
}
|
||||
|
@ -615,7 +624,7 @@ impl rtio::RtioSocket for UdpSocket {
|
|||
#[cfg(unix)] type msglen_t = libc::size_t;
|
||||
|
||||
impl rtio::RtioUdpSocket for UdpSocket {
|
||||
fn recvfrom(&mut self, buf: &mut [u8]) -> IoResult<(uint, ip::SocketAddr)> {
|
||||
fn recvfrom(&mut self, buf: &mut [u8]) -> IoResult<(uint, rtio::SocketAddr)> {
|
||||
let fd = self.fd();
|
||||
let mut storage: libc::sockaddr_storage = unsafe { mem::zeroed() };
|
||||
let storagep = &mut storage as *mut _ as *mut libc::sockaddr;
|
||||
|
@ -638,7 +647,7 @@ impl rtio::RtioUdpSocket for UdpSocket {
|
|||
})
|
||||
}
|
||||
|
||||
fn sendto(&mut self, buf: &[u8], dst: ip::SocketAddr) -> IoResult<()> {
|
||||
fn sendto(&mut self, buf: &[u8], dst: rtio::SocketAddr) -> IoResult<()> {
|
||||
let (dst, dstlen) = addr_to_sockaddr(dst);
|
||||
let dstp = &dst as *_ as *libc::sockaddr;
|
||||
let dstlen = dstlen as libc::socklen_t;
|
||||
|
@ -657,32 +666,28 @@ impl rtio::RtioUdpSocket for UdpSocket {
|
|||
|
||||
let n = try!(write(fd, self.write_deadline, buf, false, dolock, dowrite));
|
||||
if n != buf.len() {
|
||||
Err(io::IoError {
|
||||
kind: io::ShortWrite(n),
|
||||
desc: "couldn't send entire packet at once",
|
||||
detail: None,
|
||||
})
|
||||
Err(util::short_write(n, "couldn't send entire packet at once"))
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn join_multicast(&mut self, multi: ip::IpAddr) -> IoResult<()> {
|
||||
fn join_multicast(&mut self, multi: rtio::IpAddr) -> IoResult<()> {
|
||||
match multi {
|
||||
ip::Ipv4Addr(..) => {
|
||||
rtio::Ipv4Addr(..) => {
|
||||
self.set_membership(multi, libc::IP_ADD_MEMBERSHIP)
|
||||
}
|
||||
ip::Ipv6Addr(..) => {
|
||||
rtio::Ipv6Addr(..) => {
|
||||
self.set_membership(multi, libc::IPV6_ADD_MEMBERSHIP)
|
||||
}
|
||||
}
|
||||
}
|
||||
fn leave_multicast(&mut self, multi: ip::IpAddr) -> IoResult<()> {
|
||||
fn leave_multicast(&mut self, multi: rtio::IpAddr) -> IoResult<()> {
|
||||
match multi {
|
||||
ip::Ipv4Addr(..) => {
|
||||
rtio::Ipv4Addr(..) => {
|
||||
self.set_membership(multi, libc::IP_DROP_MEMBERSHIP)
|
||||
}
|
||||
ip::Ipv6Addr(..) => {
|
||||
rtio::Ipv6Addr(..) => {
|
||||
self.set_membership(multi, libc::IPV6_DROP_MEMBERSHIP)
|
||||
}
|
||||
}
|
||||
|
@ -821,7 +826,7 @@ pub fn read<T>(fd: sock_t,
|
|||
}
|
||||
|
||||
match ret {
|
||||
0 => Err(io::standard_error(io::EndOfFile)),
|
||||
0 => Err(util::eof()),
|
||||
n if n < 0 => Err(last_error()),
|
||||
n => Ok(n as uint)
|
||||
}
|
||||
|
@ -858,13 +863,9 @@ pub fn write<T>(fd: sock_t,
|
|||
// As with read(), first wait for the socket to be ready for
|
||||
// the I/O operation.
|
||||
match util::await(fd, deadline, util::Writable) {
|
||||
Err(ref e) if e.kind == io::TimedOut && written > 0 => {
|
||||
Err(ref e) if e.code == libc::EOF as uint && written > 0 => {
|
||||
assert!(deadline.is_some());
|
||||
return Err(io::IoError {
|
||||
kind: io::ShortWrite(written),
|
||||
desc: "short write",
|
||||
detail: None,
|
||||
})
|
||||
return Err(util::short_write(written, "short write"))
|
||||
}
|
||||
Err(e) => return Err(e),
|
||||
Ok(()) => {}
|
||||
|
|
|
@ -11,13 +11,12 @@
|
|||
use alloc::arc::Arc;
|
||||
use libc;
|
||||
use std::c_str::CString;
|
||||
use std::intrinsics;
|
||||
use std::io;
|
||||
use std::mem;
|
||||
use std::rt::mutex;
|
||||
use std::rt::rtio;
|
||||
use std::unstable::mutex;
|
||||
use std::rt::rtio::{IoResult, IoError};
|
||||
|
||||
use super::{IoResult, retry};
|
||||
use super::retry;
|
||||
use super::net;
|
||||
use super::util;
|
||||
use super::c;
|
||||
|
@ -34,15 +33,17 @@ fn addr_to_sockaddr_un(addr: &CString) -> IoResult<(libc::sockaddr_storage, uint
|
|||
// the sun_path length is limited to SUN_LEN (with null)
|
||||
assert!(mem::size_of::<libc::sockaddr_storage>() >=
|
||||
mem::size_of::<libc::sockaddr_un>());
|
||||
let mut storage: libc::sockaddr_storage = unsafe { intrinsics::init() };
|
||||
let mut storage: libc::sockaddr_storage = unsafe { mem::zeroed() };
|
||||
let s: &mut libc::sockaddr_un = unsafe { mem::transmute(&mut storage) };
|
||||
|
||||
let len = addr.len();
|
||||
if len > s.sun_path.len() - 1 {
|
||||
return Err(io::IoError {
|
||||
kind: io::InvalidInput,
|
||||
desc: "path must be smaller than SUN_LEN",
|
||||
detail: None,
|
||||
#[cfg(unix)] use ERROR = libc::EINVAL;
|
||||
#[cfg(windows)] use ERROR = libc::WSAEINVAL;
|
||||
return Err(IoError {
|
||||
code: ERROR as uint,
|
||||
extra: 0,
|
||||
detail: Some("path must be smaller than SUN_LEN".to_str()),
|
||||
})
|
||||
}
|
||||
s.sun_family = libc::AF_UNIX as libc::sa_family_t;
|
||||
|
@ -244,7 +245,7 @@ impl UnixAcceptor {
|
|||
if self.deadline != 0 {
|
||||
try!(util::await(self.fd(), Some(self.deadline), util::Readable));
|
||||
}
|
||||
let mut storage: libc::sockaddr_storage = unsafe { intrinsics::init() };
|
||||
let mut storage: libc::sockaddr_storage = unsafe { mem::zeroed() };
|
||||
let storagep = &mut storage as *mut libc::sockaddr_storage;
|
||||
let size = mem::size_of::<libc::sockaddr_storage>();
|
||||
let mut size = size as libc::socklen_t;
|
||||
|
|
|
@ -10,16 +10,13 @@
|
|||
|
||||
use libc::{pid_t, c_void, c_int};
|
||||
use libc;
|
||||
use std::io;
|
||||
use std::mem;
|
||||
use std::os;
|
||||
use std::ptr;
|
||||
use std::rt::rtio;
|
||||
use std::rt::rtio::ProcessConfig;
|
||||
use std::rt::rtio::{ProcessConfig, IoResult, IoError};
|
||||
use std::c_str::CString;
|
||||
use p = std::io::process;
|
||||
|
||||
use super::IoResult;
|
||||
use super::file;
|
||||
use super::util;
|
||||
|
||||
|
@ -48,7 +45,7 @@ pub struct Process {
|
|||
handle: *(),
|
||||
|
||||
/// None until finish() is called.
|
||||
exit_code: Option<p::ProcessExit>,
|
||||
exit_code: Option<rtio::ProcessExit>,
|
||||
|
||||
/// Manually delivered signal
|
||||
exit_signal: Option<int>,
|
||||
|
@ -59,7 +56,7 @@ pub struct Process {
|
|||
|
||||
#[cfg(unix)]
|
||||
enum Req {
|
||||
NewChild(libc::pid_t, Sender<p::ProcessExit>, u64),
|
||||
NewChild(libc::pid_t, Sender<rtio::ProcessExit>, u64),
|
||||
}
|
||||
|
||||
impl Process {
|
||||
|
@ -67,20 +64,21 @@ impl Process {
|
|||
/// by the OS. Operations on this process will be blocking instead of using
|
||||
/// the runtime for sleeping just this current task.
|
||||
pub fn spawn(cfg: ProcessConfig)
|
||||
-> Result<(Process, Vec<Option<file::FileDesc>>), io::IoError>
|
||||
-> IoResult<(Process, Vec<Option<file::FileDesc>>)>
|
||||
{
|
||||
// right now we only handle stdin/stdout/stderr.
|
||||
if cfg.extra_io.len() > 0 {
|
||||
return Err(super::unimpl());
|
||||
}
|
||||
|
||||
fn get_io(io: p::StdioContainer, ret: &mut Vec<Option<file::FileDesc>>)
|
||||
fn get_io(io: rtio::StdioContainer,
|
||||
ret: &mut Vec<Option<file::FileDesc>>)
|
||||
-> (Option<os::Pipe>, c_int)
|
||||
{
|
||||
match io {
|
||||
p::Ignored => { ret.push(None); (None, -1) }
|
||||
p::InheritFd(fd) => { ret.push(None); (None, fd) }
|
||||
p::CreatePipe(readable, _writable) => {
|
||||
rtio::Ignored => { ret.push(None); (None, -1) }
|
||||
rtio::InheritFd(fd) => { ret.push(None); (None, fd) }
|
||||
rtio::CreatePipe(readable, _writable) => {
|
||||
let pipe = os::pipe();
|
||||
let (theirs, ours) = if readable {
|
||||
(pipe.input, pipe.out)
|
||||
|
@ -133,7 +131,7 @@ impl rtio::RtioProcess for Process {
|
|||
self.deadline = timeout.map(|i| i + ::io::timer::now()).unwrap_or(0);
|
||||
}
|
||||
|
||||
fn wait(&mut self) -> IoResult<p::ProcessExit> {
|
||||
fn wait(&mut self) -> IoResult<rtio::ProcessExit> {
|
||||
match self.exit_code {
|
||||
Some(code) => Ok(code),
|
||||
None => {
|
||||
|
@ -143,7 +141,7 @@ impl rtio::RtioProcess for Process {
|
|||
// consider it as having died via a signal.
|
||||
let code = match self.exit_signal {
|
||||
None => code,
|
||||
Some(signal) if cfg!(windows) => p::ExitSignal(signal),
|
||||
Some(signal) if cfg!(windows) => rtio::ExitSignal(signal),
|
||||
Some(..) => code,
|
||||
};
|
||||
self.exit_code = Some(code);
|
||||
|
@ -152,7 +150,10 @@ impl rtio::RtioProcess for Process {
|
|||
}
|
||||
}
|
||||
|
||||
fn kill(&mut self, signum: int) -> Result<(), io::IoError> {
|
||||
fn kill(&mut self, signum: int) -> IoResult<()> {
|
||||
#[cfg(unix)] use ERROR = libc::EINVAL;
|
||||
#[cfg(windows)] use ERROR = libc::ERROR_NOTHING_TO_TERMINATE;
|
||||
|
||||
// On linux (and possibly other unices), a process that has exited will
|
||||
// continue to accept signals because it is "defunct". The delivery of
|
||||
// signals will only fail once the child has been reaped. For this
|
||||
|
@ -169,10 +170,10 @@ impl rtio::RtioProcess for Process {
|
|||
// and we kill it, then on unix we might ending up killing a
|
||||
// newer process that happens to have the same (re-used) id
|
||||
match self.exit_code {
|
||||
Some(..) => return Err(io::IoError {
|
||||
kind: io::OtherIoError,
|
||||
desc: "can't kill an exited process",
|
||||
detail: None,
|
||||
Some(..) => return Err(IoError {
|
||||
code: ERROR as uint,
|
||||
extra: 0,
|
||||
detail: Some("can't kill an exited process".to_str()),
|
||||
}),
|
||||
None => {}
|
||||
}
|
||||
|
@ -194,7 +195,7 @@ impl Drop for Process {
|
|||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
unsafe fn killpid(pid: pid_t, signal: int) -> Result<(), io::IoError> {
|
||||
unsafe fn killpid(pid: pid_t, signal: int) -> IoResult<()> {
|
||||
let handle = libc::OpenProcess(libc::PROCESS_TERMINATE |
|
||||
libc::PROCESS_QUERY_INFORMATION,
|
||||
libc::FALSE, pid as libc::DWORD);
|
||||
|
@ -233,7 +234,7 @@ unsafe fn killpid(pid: pid_t, signal: int) -> Result<(), io::IoError> {
|
|||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
unsafe fn killpid(pid: pid_t, signal: int) -> Result<(), io::IoError> {
|
||||
unsafe fn killpid(pid: pid_t, signal: int) -> IoResult<()> {
|
||||
let r = libc::funcs::posix88::signal::kill(pid, signal as c_int);
|
||||
super::mkerr_libc(r)
|
||||
}
|
||||
|
@ -521,12 +522,13 @@ fn spawn_process_os(cfg: ProcessConfig, in_fd: c_int, out_fd: c_int, err_fd: c_i
|
|||
(bytes[1] << 16) as i32 |
|
||||
(bytes[2] << 8) as i32 |
|
||||
(bytes[3] << 0) as i32;
|
||||
Err(io::IoError::from_errno(errno as uint, false))
|
||||
Err(IoError {
|
||||
code: errno as uint,
|
||||
detail: None,
|
||||
extra: 0,
|
||||
})
|
||||
}
|
||||
Err(e) => {
|
||||
assert!(e.kind == io::BrokenPipe ||
|
||||
e.kind == io::EndOfFile,
|
||||
"unexpected error: {}", e);
|
||||
Err(..) => {
|
||||
Ok(SpawnProcessResult {
|
||||
pid: pid,
|
||||
handle: ptr::null()
|
||||
|
@ -757,7 +759,7 @@ fn free_handle(_handle: *()) {
|
|||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn translate_status(status: c_int) -> p::ProcessExit {
|
||||
fn translate_status(status: c_int) -> rtio::ProcessExit {
|
||||
#![allow(non_snake_case_functions)]
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(target_os = "android")]
|
||||
|
@ -776,9 +778,9 @@ fn translate_status(status: c_int) -> p::ProcessExit {
|
|||
}
|
||||
|
||||
if imp::WIFEXITED(status) {
|
||||
p::ExitStatus(imp::WEXITSTATUS(status) as int)
|
||||
rtio::ExitStatus(imp::WEXITSTATUS(status) as int)
|
||||
} else {
|
||||
p::ExitSignal(imp::WTERMSIG(status) as int)
|
||||
rtio::ExitSignal(imp::WTERMSIG(status) as int)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -793,7 +795,7 @@ fn translate_status(status: c_int) -> p::ProcessExit {
|
|||
* with the same id.
|
||||
*/
|
||||
#[cfg(windows)]
|
||||
fn waitpid(pid: pid_t, deadline: u64) -> IoResult<p::ProcessExit> {
|
||||
fn waitpid(pid: pid_t, deadline: u64) -> IoResult<rtio::ProcessExit> {
|
||||
use libc::types::os::arch::extra::DWORD;
|
||||
use libc::consts::os::extra::{
|
||||
SYNCHRONIZE,
|
||||
|
@ -828,7 +830,7 @@ fn waitpid(pid: pid_t, deadline: u64) -> IoResult<p::ProcessExit> {
|
|||
}
|
||||
if status != STILL_ACTIVE {
|
||||
assert!(CloseHandle(process) != 0);
|
||||
return Ok(p::ExitStatus(status as int));
|
||||
return Ok(rtio::ExitStatus(status as int));
|
||||
}
|
||||
let interval = if deadline == 0 {
|
||||
INFINITE
|
||||
|
@ -853,7 +855,7 @@ fn waitpid(pid: pid_t, deadline: u64) -> IoResult<p::ProcessExit> {
|
|||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn waitpid(pid: pid_t, deadline: u64) -> IoResult<p::ProcessExit> {
|
||||
fn waitpid(pid: pid_t, deadline: u64) -> IoResult<rtio::ProcessExit> {
|
||||
use std::cmp;
|
||||
use std::comm;
|
||||
|
||||
|
@ -862,7 +864,7 @@ fn waitpid(pid: pid_t, deadline: u64) -> IoResult<p::ProcessExit> {
|
|||
let mut status = 0 as c_int;
|
||||
if deadline == 0 {
|
||||
return match retry(|| unsafe { c::waitpid(pid, &mut status, 0) }) {
|
||||
-1 => fail!("unknown waitpid error: {}", super::last_error()),
|
||||
-1 => fail!("unknown waitpid error: {}", super::last_error().code),
|
||||
_ => Ok(translate_status(status)),
|
||||
}
|
||||
}
|
||||
|
@ -928,8 +930,8 @@ fn waitpid(pid: pid_t, deadline: u64) -> IoResult<p::ProcessExit> {
|
|||
unsafe {
|
||||
let mut pipes = [0, ..2];
|
||||
assert_eq!(libc::pipe(pipes.as_mut_ptr()), 0);
|
||||
util::set_nonblocking(pipes[0], true).unwrap();
|
||||
util::set_nonblocking(pipes[1], true).unwrap();
|
||||
util::set_nonblocking(pipes[0], true).ok().unwrap();
|
||||
util::set_nonblocking(pipes[1], true).ok().unwrap();
|
||||
WRITE_FD = pipes[1];
|
||||
|
||||
let mut old: c::sigaction = mem::zeroed();
|
||||
|
@ -945,10 +947,10 @@ fn waitpid(pid: pid_t, deadline: u64) -> IoResult<p::ProcessExit> {
|
|||
fn waitpid_helper(input: libc::c_int,
|
||||
messages: Receiver<Req>,
|
||||
(read_fd, old): (libc::c_int, c::sigaction)) {
|
||||
util::set_nonblocking(input, true).unwrap();
|
||||
util::set_nonblocking(input, true).ok().unwrap();
|
||||
let mut set: c::fd_set = unsafe { mem::zeroed() };
|
||||
let mut tv: libc::timeval;
|
||||
let mut active = Vec::<(libc::pid_t, Sender<p::ProcessExit>, u64)>::new();
|
||||
let mut active = Vec::<(libc::pid_t, Sender<rtio::ProcessExit>, u64)>::new();
|
||||
let max = cmp::max(input, read_fd) + 1;
|
||||
|
||||
'outer: loop {
|
||||
|
@ -1094,22 +1096,23 @@ fn waitpid(pid: pid_t, deadline: u64) -> IoResult<p::ProcessExit> {
|
|||
}
|
||||
}
|
||||
|
||||
fn waitpid_nowait(pid: pid_t) -> Option<p::ProcessExit> {
|
||||
fn waitpid_nowait(pid: pid_t) -> Option<rtio::ProcessExit> {
|
||||
return waitpid_os(pid);
|
||||
|
||||
// This code path isn't necessary on windows
|
||||
#[cfg(windows)]
|
||||
fn waitpid_os(_pid: pid_t) -> Option<p::ProcessExit> { None }
|
||||
fn waitpid_os(_pid: pid_t) -> Option<rtio::ProcessExit> { None }
|
||||
|
||||
#[cfg(unix)]
|
||||
fn waitpid_os(pid: pid_t) -> Option<p::ProcessExit> {
|
||||
fn waitpid_os(pid: pid_t) -> Option<rtio::ProcessExit> {
|
||||
let mut status = 0 as c_int;
|
||||
match retry(|| unsafe {
|
||||
c::waitpid(pid, &mut status, c::WNOHANG)
|
||||
}) {
|
||||
n if n == pid => Some(translate_status(status)),
|
||||
0 => None,
|
||||
n => fail!("unknown waitpid error `{}`: {}", n, super::last_error()),
|
||||
n => fail!("unknown waitpid error `{}`: {}", n,
|
||||
super::last_error().code),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,10 +51,10 @@ use std::mem;
|
|||
use std::os;
|
||||
use std::ptr;
|
||||
use std::rt::rtio;
|
||||
use std::rt::rtio::IoResult;
|
||||
use std::sync::atomics;
|
||||
use std::comm;
|
||||
|
||||
use io::IoResult;
|
||||
use io::c;
|
||||
use io::file::FileDesc;
|
||||
use io::helper_thread::Helper;
|
||||
|
@ -67,7 +67,7 @@ pub struct Timer {
|
|||
}
|
||||
|
||||
struct Inner {
|
||||
tx: Option<Sender<()>>,
|
||||
cb: Option<Box<rtio::Callback:Send>>,
|
||||
interval: u64,
|
||||
repeat: bool,
|
||||
target: u64,
|
||||
|
@ -119,13 +119,13 @@ fn helper(input: libc::c_int, messages: Receiver<Req>, _: ()) {
|
|||
let mut timer = match active.shift() {
|
||||
Some(timer) => timer, None => return
|
||||
};
|
||||
let tx = timer.tx.take_unwrap();
|
||||
if tx.send_opt(()).is_ok() && timer.repeat {
|
||||
timer.tx = Some(tx);
|
||||
let mut cb = timer.cb.take_unwrap();
|
||||
cb.call();
|
||||
if timer.repeat {
|
||||
timer.cb = Some(cb);
|
||||
timer.target += timer.interval;
|
||||
insert(timer, active);
|
||||
} else {
|
||||
drop(tx);
|
||||
dead.push((timer.id, timer));
|
||||
}
|
||||
}
|
||||
|
@ -190,7 +190,7 @@ fn helper(input: libc::c_int, messages: Receiver<Req>, _: ()) {
|
|||
|
||||
// drain the file descriptor
|
||||
let mut buf = [0];
|
||||
assert_eq!(fd.inner_read(buf).unwrap(), 1);
|
||||
assert_eq!(fd.inner_read(buf).ok().unwrap(), 1);
|
||||
}
|
||||
|
||||
-1 if os::errno() == libc::EINTR as int => {}
|
||||
|
@ -209,7 +209,7 @@ impl Timer {
|
|||
Ok(Timer {
|
||||
id: id,
|
||||
inner: Some(box Inner {
|
||||
tx: None,
|
||||
cb: None,
|
||||
interval: 0,
|
||||
target: 0,
|
||||
repeat: false,
|
||||
|
@ -245,38 +245,34 @@ impl Timer {
|
|||
impl rtio::RtioTimer for Timer {
|
||||
fn sleep(&mut self, msecs: u64) {
|
||||
let mut inner = self.inner();
|
||||
inner.tx = None; // cancel any previous request
|
||||
inner.cb = None; // cancel any previous request
|
||||
self.inner = Some(inner);
|
||||
|
||||
Timer::sleep(msecs);
|
||||
}
|
||||
|
||||
fn oneshot(&mut self, msecs: u64) -> Receiver<()> {
|
||||
fn oneshot(&mut self, msecs: u64, cb: Box<rtio::Callback:Send>) {
|
||||
let now = now();
|
||||
let mut inner = self.inner();
|
||||
|
||||
let (tx, rx) = channel();
|
||||
inner.repeat = false;
|
||||
inner.tx = Some(tx);
|
||||
inner.cb = Some(cb);
|
||||
inner.interval = msecs;
|
||||
inner.target = now + msecs;
|
||||
|
||||
unsafe { HELPER.send(NewTimer(inner)); }
|
||||
return rx;
|
||||
}
|
||||
|
||||
fn period(&mut self, msecs: u64) -> Receiver<()> {
|
||||
fn period(&mut self, msecs: u64, cb: Box<rtio::Callback:Send>) {
|
||||
let now = now();
|
||||
let mut inner = self.inner();
|
||||
|
||||
let (tx, rx) = channel();
|
||||
inner.repeat = true;
|
||||
inner.tx = Some(tx);
|
||||
inner.cb = Some(cb);
|
||||
inner.interval = msecs;
|
||||
inner.target = now + msecs;
|
||||
|
||||
unsafe { HELPER.send(NewTimer(inner)); }
|
||||
return rx;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,11 +9,10 @@
|
|||
// except according to those terms.
|
||||
|
||||
use libc;
|
||||
use std::io::IoResult;
|
||||
use std::io;
|
||||
use std::mem;
|
||||
use std::os;
|
||||
use std::ptr;
|
||||
use std::rt::rtio::{IoResult, IoError};
|
||||
|
||||
use super::c;
|
||||
use super::net;
|
||||
|
@ -25,10 +24,30 @@ pub enum SocketStatus {
|
|||
Writable,
|
||||
}
|
||||
|
||||
pub fn timeout(desc: &'static str) -> io::IoError {
|
||||
io::IoError {
|
||||
kind: io::TimedOut,
|
||||
desc: desc,
|
||||
pub fn timeout(desc: &'static str) -> IoError {
|
||||
#[cfg(unix)] use ERROR = libc::ETIMEDOUT;
|
||||
#[cfg(windows)] use ERROR = libc::ERROR_OPERATION_ABORTED;
|
||||
IoError {
|
||||
code: ERROR as uint,
|
||||
extra: 0,
|
||||
detail: Some(desc.to_str()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn short_write(n: uint, desc: &'static str) -> IoError {
|
||||
#[cfg(unix)] use ERROR = libc::EAGAIN;
|
||||
#[cfg(windows)] use ERROR = libc::ERROR_OPERATION_ABORTED;
|
||||
IoError {
|
||||
code: ERROR as uint,
|
||||
extra: n,
|
||||
detail: Some(desc.to_str()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn eof() -> IoError {
|
||||
IoError {
|
||||
code: libc::EOF as uint,
|
||||
extra: 0,
|
||||
detail: None,
|
||||
}
|
||||
}
|
||||
|
@ -100,7 +119,11 @@ pub fn connect_timeout(fd: net::sock_t,
|
|||
if err == 0 {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(io::IoError::from_errno(err as uint, true))
|
||||
Err(IoError {
|
||||
code: err as uint,
|
||||
extra: 0,
|
||||
detail: Some(os::error_string(err as uint)),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,15 +17,13 @@
|
|||
use std::any::Any;
|
||||
use std::mem;
|
||||
use std::rt::bookkeeping;
|
||||
use std::rt::env;
|
||||
use std::rt::local::Local;
|
||||
use std::rt::mutex::NativeMutex;
|
||||
use std::rt::rtio;
|
||||
use std::rt::stack;
|
||||
use std::rt::task::{Task, BlockedTask, SendMessage};
|
||||
use std::rt::task::{Task, BlockedTask, TaskOpts};
|
||||
use std::rt::thread::Thread;
|
||||
use std::rt;
|
||||
use std::task::TaskOpts;
|
||||
use std::unstable::mutex::NativeMutex;
|
||||
|
||||
use io;
|
||||
use task;
|
||||
|
@ -51,27 +49,19 @@ fn ops() -> Box<Ops> {
|
|||
|
||||
/// Spawns a function with the default configuration
|
||||
pub fn spawn(f: proc():Send) {
|
||||
spawn_opts(TaskOpts::new(), f)
|
||||
spawn_opts(TaskOpts { name: None, stack_size: None, on_exit: None }, f)
|
||||
}
|
||||
|
||||
/// Spawns a new task given the configuration options and a procedure to run
|
||||
/// inside the task.
|
||||
pub fn spawn_opts(opts: TaskOpts, f: proc():Send) {
|
||||
let TaskOpts {
|
||||
notify_chan, name, stack_size,
|
||||
stderr, stdout,
|
||||
} = opts;
|
||||
let TaskOpts { name, stack_size, on_exit } = opts;
|
||||
|
||||
let mut task = box Task::new();
|
||||
task.name = name;
|
||||
task.stderr = stderr;
|
||||
task.stdout = stdout;
|
||||
match notify_chan {
|
||||
Some(chan) => { task.death.on_exit = Some(SendMessage(chan)); }
|
||||
None => {}
|
||||
}
|
||||
task.death.on_exit = on_exit;
|
||||
|
||||
let stack = stack_size.unwrap_or(env::min_stack());
|
||||
let stack = stack_size.unwrap_or(rt::min_stack());
|
||||
let task = task;
|
||||
let ops = ops();
|
||||
|
||||
|
@ -267,9 +257,8 @@ impl rt::Runtime for Ops {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::rt::local::Local;
|
||||
use std::rt::task::Task;
|
||||
use std::rt::task::{Task, TaskOpts};
|
||||
use std::task;
|
||||
use std::task::TaskOpts;
|
||||
use super::{spawn, spawn_opts, Ops};
|
||||
|
||||
#[test]
|
||||
|
@ -297,7 +286,7 @@ mod tests {
|
|||
opts.name = Some("test".into_maybe_owned());
|
||||
opts.stack_size = Some(20 * 4096);
|
||||
let (tx, rx) = channel();
|
||||
opts.notify_chan = Some(tx);
|
||||
opts.on_exit = Some(proc(r) tx.send(r));
|
||||
spawn_opts(opts, proc() {});
|
||||
assert!(rx.recv().is_ok());
|
||||
}
|
||||
|
@ -306,7 +295,7 @@ mod tests {
|
|||
fn smoke_opts_fail() {
|
||||
let mut opts = TaskOpts::new();
|
||||
let (tx, rx) = channel();
|
||||
opts.notify_chan = Some(tx);
|
||||
opts.on_exit = Some(proc(r) tx.send(r));
|
||||
spawn_opts(opts, proc() { fail!() });
|
||||
assert!(rx.recv().is_err());
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue