From 51348b068b88d71426d9de93762575cd2bb9a5f5 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 4 Jun 2014 00:00:49 -0700 Subject: [PATCH] native: Deal with the rtio changes --- src/libnative/io/addrinfo.rs | 29 +++-- src/libnative/io/file_unix.rs | 181 +++++++++++++----------------- src/libnative/io/helper_thread.rs | 6 +- src/libnative/io/mod.rs | 114 ++++++++++--------- src/libnative/io/net.rs | 101 ++++++++--------- src/libnative/io/pipe_unix.rs | 21 ++-- src/libnative/io/process.rs | 83 +++++++------- src/libnative/io/timer_unix.rs | 30 +++-- src/libnative/io/util.rs | 37 ++++-- src/libnative/task.rs | 29 ++--- 10 files changed, 313 insertions(+), 318 deletions(-) diff --git a/src/libnative/io/addrinfo.rs b/src/libnative/io/addrinfo.rs index 6bc41a9c4c5..b79061dd9d6 100644 --- a/src/libnative/io/addrinfo.rs +++ b/src/libnative/io/addrinfo.rs @@ -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) -> Result, IoError> { + hint: Option) + -> Result, 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), } } diff --git a/src/libnative/io/file_unix.rs b/src/libnative/io/file_unix.rs index 3182b061e52..fda9b7b1932 100644 --- a/src/libnative/io/file_unix.rs +++ b/src/libnative/io/file_unix.rs @@ -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 { + pub fn inner_read(&mut self, buf: &mut [u8]) -> IoResult { 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 { - 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 { + fn read(&mut self, buf: &mut [u8]) -> IoResult { 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 { + fn pread(&mut self, buf: &mut [u8], offset: u64) -> IoResult { 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 { + fn seek(&mut self, pos: i64, whence: rtio::SeekStyle) -> IoResult { 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 { + fn tell(&self) -> IoResult { 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 { + fn fstat(&mut self) -> IoResult { 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 { + fn read(&mut self, buf: &mut [u8]) -> IoResult { 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 { @@ -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) {} fn set_read_timeout(&mut self, _t: Option) {} @@ -199,16 +187,16 @@ impl rtio::RtioPipe for FileDesc { } impl rtio::RtioTTY for FileDesc { - fn read(&mut self, buf: &mut [u8]) -> Result { + fn read(&mut self, buf: &mut [u8]) -> IoResult { 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 { + fn read(&mut self, buf: &mut [u8]) -> IoResult { 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 { + fn pread(&mut self, buf: &mut [u8], offset: u64) -> IoResult { 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 { + fn seek(&mut self, pos: i64, style: rtio::SeekStyle) -> IoResult { 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 { + fn tell(&self) -> IoResult { 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 { + fn fstat(&mut self) -> IoResult { 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 { +pub fn open(path: &CString, fm: rtio::FileMode, fa: rtio::FileAccess) + -> IoResult +{ 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 { +pub fn stat(p: &CString) -> IoResult { 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 { } } -pub fn lstat(p: &CString) -> IoResult { +pub fn lstat(p: &CString) -> IoResult { 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); diff --git a/src/libnative/io/helper_thread.rs b/src/libnative/io/helper_thread.rs index 2260d74e161..443c82c6a54 100644 --- a/src/libnative/io/helper_thread.rs +++ b/src/libnative/io/helper_thread.rs @@ -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 { 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) { diff --git a/src/libnative/io/mod.rs b/src/libnative/io/mod.rs index a17a683646a..3b0dbe2d0dc 100644 --- a/src/libnative/io/mod.rs +++ b/src/libnative/io/mod.rs @@ -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 = Result; - 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) -> IoResult> { + fn tcp_connect(&mut self, addr: rtio::SocketAddr, + timeout: Option) + -> IoResult> + { net::TcpStream::connect(addr, timeout).map(|s| { - box s as Box + box s as Box }) } - fn tcp_bind(&mut self, addr: SocketAddr) - -> IoResult> { + fn tcp_bind(&mut self, addr: rtio::SocketAddr) + -> IoResult> { net::TcpListener::bind(addr).map(|s| { - box s as Box + box s as Box }) } - fn udp_bind(&mut self, addr: SocketAddr) - -> IoResult> { - net::UdpSocket::bind(addr).map(|u| box u as Box) + fn udp_bind(&mut self, addr: rtio::SocketAddr) + -> IoResult> { + net::UdpSocket::bind(addr).map(|u| { + box u as Box + }) } fn unix_bind(&mut self, path: &CString) - -> IoResult> { + -> IoResult> { pipe::UnixListener::bind(path).map(|s| { - box s as Box + box s as Box }) } fn unix_connect(&mut self, path: &CString, - timeout: Option) -> IoResult> { + timeout: Option) -> IoResult> { pipe::UnixStream::connect(path, timeout).map(|s| { - box s as Box + box s as Box }) } fn get_host_addresses(&mut self, host: Option<&str>, servname: Option<&str>, - hint: Option) -> IoResult> { + hint: Option) + -> IoResult> + { addrinfo::GetAddrInfoRequest::run(host, servname, hint) } // filesystem operations - fn fs_from_raw_fd(&mut self, fd: c_int, close: CloseBehavior) - -> Box { + fn fs_from_raw_fd(&mut self, fd: c_int, close: rtio::CloseBehavior) + -> Box { let close = match close { rtio::CloseSynchronously | rtio::CloseAsynchronously => true, rtio::DontClose => false }; - box file::FileDesc::new(fd, close) as Box + box file::FileDesc::new(fd, close) as Box } - fn fs_open(&mut self, path: &CString, fm: io::FileMode, fa: io::FileAccess) - -> IoResult> { - file::open(path, fm, fa).map(|fd| box fd as Box) + fn fs_open(&mut self, path: &CString, fm: rtio::FileMode, + fa: rtio::FileAccess) + -> IoResult> + { + file::open(path, fm, fa).map(|fd| box fd as Box) } fn fs_unlink(&mut self, path: &CString) -> IoResult<()> { file::unlink(path) } - fn fs_stat(&mut self, path: &CString) -> IoResult { + fn fs_stat(&mut self, path: &CString) -> IoResult { 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> { file::readdir(path) } - fn fs_lstat(&mut self, path: &CString) -> IoResult { + fn fs_lstat(&mut self, path: &CString) -> IoResult { 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> { - timer::Timer::new().map(|t| box t as Box) + fn timer_init(&mut self) -> IoResult> { + timer::Timer::new().map(|t| box t as Box) } - fn spawn(&mut self, cfg: ProcessConfig) - -> IoResult<(Box, - Vec>>)> { + fn spawn(&mut self, cfg: rtio::ProcessConfig) + -> IoResult<(Box, + Vec>>)> { process::Process::spawn(cfg).map(|(p, io)| { - (box p as Box, + (box p as Box, io.move_iter().map(|p| p.map(|p| { - box p as Box + box p as Box })).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> { - Ok(box file::FileDesc::new(fd, true) as Box) + fn pipe_open(&mut self, fd: c_int) -> IoResult> { + Ok(box file::FileDesc::new(fd, true) as Box) } fn tty_open(&mut self, fd: c_int, _readable: bool) - -> IoResult> { + -> IoResult> { + #[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) + Ok(box file::FileDesc::new(fd, true) as Box) } 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) - -> IoResult> { + fn signal(&mut self, _signal: int, _cb: Box) + -> IoResult> { Err(unimpl()) } } diff --git a/src/libnative/io/net.rs b/src/libnative/io/net.rs index 26307feae91..68cc5273b5e 100644 --- a/src/libnative/io/net.rs +++ b/src/libnative/io/net.rs @@ -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 { +fn socket(addr: rtio::SocketAddr, ty: libc::c_int) -> IoResult { 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(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 + -> IoResult { let mut storage: libc::sockaddr_storage = unsafe { mem::zeroed() }; let mut len = mem::size_of::() 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 { + len: uint) -> IoResult { match storage.ss_family as libc::c_int { libc::AF_INET => { assert!(len as uint >= mem::size_of::()); @@ -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) -> IoResult { 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 { + fn peer_name(&mut self) -> IoResult { 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 { + fn socket_name(&mut self) -> IoResult { sockname(self.fd(), libc::getsockname) } } @@ -436,7 +445,7 @@ pub struct TcpListener { } impl TcpListener { - pub fn bind(addr: ip::SocketAddr) -> IoResult { + pub fn bind(addr: rtio::SocketAddr) -> IoResult { 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 { + fn socket_name(&mut self) -> IoResult { sockname(self.fd(), libc::getsockname) } } @@ -512,7 +521,7 @@ impl TcpAcceptor { } impl rtio::RtioSocket for TcpAcceptor { - fn socket_name(&mut self) -> IoResult { + fn socket_name(&mut self) -> IoResult { sockname(self.fd(), libc::getsockname) } } @@ -540,7 +549,7 @@ pub struct UdpSocket { } impl UdpSocket { - pub fn bind(addr: ip::SocketAddr) -> IoResult { + pub fn bind(addr: rtio::SocketAddr) -> IoResult { 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 { + fn socket_name(&mut self) -> IoResult { 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(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(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(()) => {} diff --git a/src/libnative/io/pipe_unix.rs b/src/libnative/io/pipe_unix.rs index a53a58b6cec..7a1134fbe59 100644 --- a/src/libnative/io/pipe_unix.rs +++ b/src/libnative/io/pipe_unix.rs @@ -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::() >= mem::size_of::()); - 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::(); let mut size = size as libc::socklen_t; diff --git a/src/libnative/io/process.rs b/src/libnative/io/process.rs index 4b75e1b7359..8b3f4debe5d 100644 --- a/src/libnative/io/process.rs +++ b/src/libnative/io/process.rs @@ -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, + exit_code: Option, /// Manually delivered signal exit_signal: Option, @@ -59,7 +56,7 @@ pub struct Process { #[cfg(unix)] enum Req { - NewChild(libc::pid_t, Sender, u64), + NewChild(libc::pid_t, Sender, 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>), io::IoError> + -> IoResult<(Process, Vec>)> { // 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>) + fn get_io(io: rtio::StdioContainer, + ret: &mut Vec>) -> (Option, 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 { + fn wait(&mut self) -> IoResult { 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 { +fn waitpid(pid: pid_t, deadline: u64) -> IoResult { 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 { } 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 { } #[cfg(unix)] -fn waitpid(pid: pid_t, deadline: u64) -> IoResult { +fn waitpid(pid: pid_t, deadline: u64) -> IoResult { use std::cmp; use std::comm; @@ -862,7 +864,7 @@ fn waitpid(pid: pid_t, deadline: u64) -> IoResult { 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 { 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 { fn waitpid_helper(input: libc::c_int, messages: Receiver, (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, u64)>::new(); + let mut active = Vec::<(libc::pid_t, Sender, u64)>::new(); let max = cmp::max(input, read_fd) + 1; 'outer: loop { @@ -1094,22 +1096,23 @@ fn waitpid(pid: pid_t, deadline: u64) -> IoResult { } } -fn waitpid_nowait(pid: pid_t) -> Option { +fn waitpid_nowait(pid: pid_t) -> Option { return waitpid_os(pid); // This code path isn't necessary on windows #[cfg(windows)] - fn waitpid_os(_pid: pid_t) -> Option { None } + fn waitpid_os(_pid: pid_t) -> Option { None } #[cfg(unix)] - fn waitpid_os(pid: pid_t) -> Option { + fn waitpid_os(pid: pid_t) -> Option { 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), } } } diff --git a/src/libnative/io/timer_unix.rs b/src/libnative/io/timer_unix.rs index 8aa8b12b26d..11f9c4b3d8c 100644 --- a/src/libnative/io/timer_unix.rs +++ b/src/libnative/io/timer_unix.rs @@ -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>, + cb: Option>, interval: u64, repeat: bool, target: u64, @@ -119,13 +119,13 @@ fn helper(input: libc::c_int, messages: Receiver, _: ()) { 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, _: ()) { // 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) { 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) { 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; } } diff --git a/src/libnative/io/util.rs b/src/libnative/io/util.rs index fe7a58a5e68..a3c5349fa45 100644 --- a/src/libnative/io/util.rs +++ b/src/libnative/io/util.rs @@ -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)), + }) } } } diff --git a/src/libnative/task.rs b/src/libnative/task.rs index 4183dec19d0..f16c41d4e28 100644 --- a/src/libnative/task.rs +++ b/src/libnative/task.rs @@ -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 { /// 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()); }