// 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());
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
});
#[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),
}
}
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;
// 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,
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,
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 {
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())
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")]
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)),
}
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> {
// 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>) {}
}
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 }
}
}
- 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,
}
});
if ret == 0 {
- Err(io::standard_error(io::EndOfFile))
+ Err(util::eof())
} else if ret < 0 {
Err(super::last_error())
} else {
}
}
- 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,
}
}
- 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 {
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())
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())
}
}
}
}
-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) }) {
}
}
-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)
}))
}
}))
}
-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)
}))
}
}))
}
-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")]
#[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)),
}
}
-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)),
#[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]
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) => {
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);
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;
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,
}
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) {
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;
#[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
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<()> {
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<()> {
}
// 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())
}
}
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;
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) |
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),
}
}
-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) {
}
}
-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()),
}
#[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()
}
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;
}
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>());
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),
})
}
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,
+ })
}
}
}
}
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));
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<()> {
}
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)
}
}
}
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) };
}
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)
}
}
}
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)
}
}
}
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)),
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) => {
}
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)
}
}
#[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;
})
}
- 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;
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)
}
}
}
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)
}
// 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(()) => {}
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;
// 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;
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;
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;
handle: *(),
/// None until finish() is called.
- exit_code: Option<p::ProcessExit>,
+ exit_code: Option<rtio::ProcessExit>,
/// Manually delivered signal
exit_signal: Option<int>,
#[cfg(unix)]
enum Req {
- NewChild(libc::pid_t, Sender<p::ProcessExit>, u64),
+ NewChild(libc::pid_t, Sender<rtio::ProcessExit>, u64),
}
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)
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 => {
// 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);
}
}
- 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
// 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 => {}
}
}
#[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);
}
#[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)
}
(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()
}
#[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")]
}
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)
}
}
* 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,
}
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
}
#[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;
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)),
}
}
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();
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 {
}
}
-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),
}
}
}
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;
}
struct Inner {
- tx: Option<Sender<()>>,
+ cb: Option<Box<rtio::Callback:Send>>,
interval: u64,
repeat: bool,
target: u64,
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));
}
}
// 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 => {}
Ok(Timer {
id: id,
inner: Some(box Inner {
- tx: None,
+ cb: None,
interval: 0,
target: 0,
repeat: false,
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;
}
}
// 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;
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,
}
}
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)),
+ })
}
}
}
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;
/// 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();
#[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]
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());
}
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());
}