mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-17 01:13:11 +00:00
Implement native TCP I/O
This commit is contained in:
parent
1763f36c9d
commit
2a4f9d69af
@ -26,7 +26,7 @@ use super::IoResult;
|
||||
#[cfg(windows)] use std::ptr;
|
||||
#[cfg(windows)] use std::str;
|
||||
|
||||
fn keep_going(data: &[u8], f: |*u8, uint| -> i64) -> i64 {
|
||||
pub fn keep_going(data: &[u8], f: |*u8, uint| -> i64) -> i64 {
|
||||
#[cfg(windows)] static eintr: int = 0; // doesn't matter
|
||||
#[cfg(not(windows))] static eintr: int = libc::EINTR as int;
|
||||
|
||||
@ -92,7 +92,7 @@ impl FileDesc {
|
||||
Ok(ret as uint)
|
||||
}
|
||||
}
|
||||
fn inner_write(&mut self, buf: &[u8]) -> Result<(), IoError> {
|
||||
pub fn inner_write(&mut self, buf: &[u8]) -> Result<(), IoError> {
|
||||
#[cfg(windows)] type wlen = libc::c_uint;
|
||||
#[cfg(not(windows))] type wlen = libc::size_t;
|
||||
let ret = keep_going(buf, |buf, len| {
|
||||
@ -106,6 +106,8 @@ impl FileDesc {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn fd(&self) -> fd_t { self.fd }
|
||||
}
|
||||
|
||||
impl io::Reader for FileDesc {
|
||||
@ -902,7 +904,7 @@ pub fn utime(p: &CString, atime: u64, mtime: u64) -> IoResult<()> {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{CFile, FileDesc, CloseFd};
|
||||
use super::{CFile, FileDesc};
|
||||
use std::io;
|
||||
use std::libc;
|
||||
use std::os;
|
||||
|
@ -44,6 +44,7 @@ pub use self::process::Process;
|
||||
// Native I/O implementations
|
||||
pub mod file;
|
||||
pub mod process;
|
||||
pub mod net;
|
||||
|
||||
type IoResult<T> = Result<T, IoError>;
|
||||
|
||||
@ -60,7 +61,20 @@ fn translate_error(errno: i32, detail: bool) -> IoError {
|
||||
fn get_err(errno: i32) -> (io::IoErrorKind, &'static str) {
|
||||
match errno {
|
||||
libc::EOF => (io::EndOfFile, "end of file"),
|
||||
_ => (io::OtherIoError, "unknown error"),
|
||||
libc::WSAECONNREFUSED => (io::ConnectionRefused, "connection refused"),
|
||||
libc::WSAECONNRESET => (io::ConnectionReset, "connection reset"),
|
||||
libc::WSAEACCES => (io::PermissionDenied, "permission denied"),
|
||||
libc::WSAEWOULDBLOCK =>
|
||||
(io::ResourceUnavailable, "resource temporarily unavailable"),
|
||||
libc::WSAENOTCONN => (io::NotConnected, "not connected"),
|
||||
libc::WSAECONNABORTED => (io::ConnectionAborted, "connection aborted"),
|
||||
libc::WSAEADDRNOTAVAIL => (io::ConnectionRefused, "address not available"),
|
||||
libc::WSAEADDRINUSE => (io::ConnectionRefused, "address in use"),
|
||||
|
||||
x => {
|
||||
debug!("ignoring {}: {}", x, os::last_os_error());
|
||||
(io::OtherIoError, "unknown error")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -69,13 +83,25 @@ fn translate_error(errno: i32, detail: bool) -> IoError {
|
||||
// XXX: this should probably be a bit more descriptive...
|
||||
match errno {
|
||||
libc::EOF => (io::EndOfFile, "end of file"),
|
||||
libc::ECONNREFUSED => (io::ConnectionRefused, "connection refused"),
|
||||
libc::ECONNRESET => (io::ConnectionReset, "connection reset"),
|
||||
libc::EPERM | libc::EACCES =>
|
||||
(io::PermissionDenied, "permission denied"),
|
||||
libc::EPIPE => (io::BrokenPipe, "broken pipe"),
|
||||
libc::ENOTCONN => (io::NotConnected, "not connected"),
|
||||
libc::ECONNABORTED => (io::ConnectionAborted, "connection aborted"),
|
||||
libc::EADDRNOTAVAIL => (io::ConnectionRefused, "address not available"),
|
||||
libc::EADDRINUSE => (io::ConnectionRefused, "address in use"),
|
||||
|
||||
// These two constants can have the same value on some systems, but
|
||||
// different values on others, so we can't use a match clause
|
||||
x if x == libc::EAGAIN || x == libc::EWOULDBLOCK =>
|
||||
(io::ResourceUnavailable, "resource temporarily unavailable"),
|
||||
|
||||
_ => (io::OtherIoError, "unknown error"),
|
||||
x => {
|
||||
debug!("ignoring {}: {}", x, os::last_os_error());
|
||||
(io::OtherIoError, "unknown error")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -121,15 +147,24 @@ fn retry(f: || -> libc::c_int) -> IoResult<libc::c_int> {
|
||||
|
||||
/// Implementation of rt::rtio's IoFactory trait to generate handles to the
|
||||
/// native I/O functionality.
|
||||
pub struct IoFactory;
|
||||
pub struct IoFactory {
|
||||
priv cannot_construct_outside_of_this_module: ()
|
||||
}
|
||||
|
||||
impl IoFactory {
|
||||
pub fn new() -> IoFactory {
|
||||
net::init();
|
||||
IoFactory { cannot_construct_outside_of_this_module: () }
|
||||
}
|
||||
}
|
||||
|
||||
impl rtio::IoFactory for IoFactory {
|
||||
// networking
|
||||
fn tcp_connect(&mut self, _addr: SocketAddr) -> IoResult<~RtioTcpStream> {
|
||||
Err(unimpl())
|
||||
fn tcp_connect(&mut self, addr: SocketAddr) -> IoResult<~RtioTcpStream> {
|
||||
net::TcpStream::connect(addr).map(|s| ~s as ~RtioTcpStream)
|
||||
}
|
||||
fn tcp_bind(&mut self, _addr: SocketAddr) -> IoResult<~RtioTcpListener> {
|
||||
Err(unimpl())
|
||||
fn tcp_bind(&mut self, addr: SocketAddr) -> IoResult<~RtioTcpListener> {
|
||||
net::TcpListener::bind(addr).map(|s| ~s as ~RtioTcpListener)
|
||||
}
|
||||
fn udp_bind(&mut self, _addr: SocketAddr) -> IoResult<~RtioUdpSocket> {
|
||||
Err(unimpl())
|
||||
@ -217,9 +252,7 @@ impl rtio::IoFactory for IoFactory {
|
||||
}
|
||||
fn tty_open(&mut self, fd: c_int, _readable: bool) -> IoResult<~RtioTTY> {
|
||||
if unsafe { libc::isatty(fd) } != 0 {
|
||||
// Don't ever close the stdio file descriptors, nothing good really
|
||||
// comes of that.
|
||||
Ok(~file::FileDesc::new(fd, fd > libc::STDERR_FILENO) as ~RtioTTY)
|
||||
Ok(~file::FileDesc::new(fd, true) as ~RtioTTY)
|
||||
} else {
|
||||
Err(IoError {
|
||||
kind: io::MismatchedFileTypeForOperation,
|
||||
|
412
src/libnative/io/net.rs
Normal file
412
src/libnative/io/net.rs
Normal file
@ -0,0 +1,412 @@
|
||||
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use std::cast;
|
||||
use std::io::net::ip;
|
||||
use std::io;
|
||||
use std::libc;
|
||||
use std::mem;
|
||||
use std::rt::rtio;
|
||||
use std::unstable::intrinsics;
|
||||
|
||||
use super::IoResult;
|
||||
use super::file::keep_going;
|
||||
|
||||
#[cfg(windows)] pub type sock_t = libc::SOCKET;
|
||||
#[cfg(unix)] pub type sock_t = super::file::fd_t;
|
||||
|
||||
pub struct TcpStream {
|
||||
priv fd: sock_t,
|
||||
}
|
||||
|
||||
#[cfg(target_endian = "big")] pub fn htons(x: u16) -> u16 { x }
|
||||
#[cfg(target_endian = "big")] pub fn ntohs(x: u16) -> u16 { x }
|
||||
#[cfg(target_endian = "little")]
|
||||
pub fn htons(u: u16) -> u16 {
|
||||
unsafe { intrinsics::bswap16(u as i16) as u16 }
|
||||
}
|
||||
#[cfg(target_endian = "little")]
|
||||
pub fn ntohs(u: u16) -> u16 {
|
||||
unsafe { intrinsics::bswap16(u as i16) as u16 }
|
||||
}
|
||||
|
||||
fn addr_to_sockaddr(addr: ip::SocketAddr) -> (libc::sockaddr_storage, uint) {
|
||||
unsafe {
|
||||
let storage: libc::sockaddr_storage = intrinsics::init();
|
||||
let len = match addr.ip {
|
||||
ip::Ipv4Addr(a, b, c, d) => {
|
||||
let storage: *mut libc::sockaddr_in = cast::transmute(&storage);
|
||||
(*storage).sin_family = libc::AF_INET as libc::sa_family_t;
|
||||
(*storage).sin_port = htons(addr.port);
|
||||
(*storage).sin_addr.s_addr = (d as u32 << 24) |
|
||||
(c as u32 << 16) |
|
||||
(b as u32 << 8) |
|
||||
(a as u32 << 0);
|
||||
mem::size_of::<libc::sockaddr_in>()
|
||||
}
|
||||
ip::Ipv6Addr(a, b, c, d, e, f, g, h) => {
|
||||
let storage: *mut libc::sockaddr_in6 = cast::transmute(&storage);
|
||||
(*storage).sin6_family = libc::AF_INET6 as libc::sa_family_t;
|
||||
(*storage).sin6_port = htons(addr.port);
|
||||
(*storage).sin6_addr.s6_addr[0] = htons(a);
|
||||
(*storage).sin6_addr.s6_addr[1] = htons(b);
|
||||
(*storage).sin6_addr.s6_addr[2] = htons(c);
|
||||
(*storage).sin6_addr.s6_addr[3] = htons(d);
|
||||
(*storage).sin6_addr.s6_addr[4] = htons(e);
|
||||
(*storage).sin6_addr.s6_addr[5] = htons(f);
|
||||
(*storage).sin6_addr.s6_addr[6] = htons(g);
|
||||
(*storage).sin6_addr.s6_addr[7] = htons(h);
|
||||
mem::size_of::<libc::sockaddr_in6>()
|
||||
}
|
||||
};
|
||||
return (storage, len);
|
||||
}
|
||||
}
|
||||
|
||||
fn socket(addr: ip::SocketAddr) -> IoResult<sock_t> {
|
||||
unsafe {
|
||||
let fam = match addr.ip {
|
||||
ip::Ipv4Addr(..) => libc::AF_INET,
|
||||
ip::Ipv6Addr(..) => libc::AF_INET6,
|
||||
};
|
||||
match libc::socket(fam, libc::SOCK_STREAM, 0) {
|
||||
-1 => Err(super::last_error()),
|
||||
fd => Ok(fd),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn sockname(fd: sock_t,
|
||||
f: extern "system" unsafe fn(sock_t, *mut libc::sockaddr,
|
||||
*mut libc::socklen_t) -> libc::c_int)
|
||||
-> IoResult<ip::SocketAddr>
|
||||
{
|
||||
let mut storage: libc::sockaddr_storage = unsafe { intrinsics::init() };
|
||||
let mut len = mem::size_of::<libc::sockaddr_storage>() as libc::socklen_t;
|
||||
unsafe {
|
||||
let storage = &mut storage as *mut libc::sockaddr_storage;
|
||||
let ret = f(fd,
|
||||
storage as *mut libc::sockaddr,
|
||||
&mut len as *mut libc::socklen_t);
|
||||
if ret != 0 {
|
||||
return Err(super::last_error())
|
||||
}
|
||||
}
|
||||
match storage.ss_family as libc::c_int {
|
||||
libc::AF_INET => {
|
||||
assert!(len as uint >= mem::size_of::<libc::sockaddr_in>());
|
||||
let storage: &mut libc::sockaddr_in = unsafe {
|
||||
cast::transmute(&mut storage)
|
||||
};
|
||||
let addr = storage.sin_addr.s_addr as u32;
|
||||
let a = (addr >> 0) as u8;
|
||||
let b = (addr >> 8) as u8;
|
||||
let c = (addr >> 16) as u8;
|
||||
let d = (addr >> 24) as u8;
|
||||
Ok(ip::SocketAddr {
|
||||
ip: ip::Ipv4Addr(a, b, c, d),
|
||||
port: ntohs(storage.sin_port),
|
||||
})
|
||||
}
|
||||
libc::AF_INET6 => {
|
||||
assert!(len as uint >= mem::size_of::<libc::sockaddr_in6>());
|
||||
let storage: &mut libc::sockaddr_in6 = unsafe {
|
||||
cast::transmute(&mut storage)
|
||||
};
|
||||
let a = ntohs(storage.sin6_addr.s6_addr[0]);
|
||||
let b = ntohs(storage.sin6_addr.s6_addr[1]);
|
||||
let c = ntohs(storage.sin6_addr.s6_addr[2]);
|
||||
let d = ntohs(storage.sin6_addr.s6_addr[3]);
|
||||
let e = ntohs(storage.sin6_addr.s6_addr[4]);
|
||||
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),
|
||||
port: ntohs(storage.sin6_port),
|
||||
})
|
||||
}
|
||||
_ => {
|
||||
Err(io::standard_error(io::OtherIoError))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
pub fn init() {}
|
||||
|
||||
#[cfg(windows)]
|
||||
pub fn init() {
|
||||
static WSADESCRIPTION_LEN: uint = 256;
|
||||
static WSASYS_STATUS_LEN: uint = 128;
|
||||
struct WSADATA {
|
||||
wVersion: libc::WORD,
|
||||
wHighVersion: libc::WORD,
|
||||
szDescription: [u8, ..WSADESCRIPTION_LEN + 1],
|
||||
szSystemStatus: [u8, ..WSASYS_STATUS_LEN + 1],
|
||||
iMaxSockets: u16,
|
||||
iMaxUdpDg: u16,
|
||||
lpVendorInfo: *u8,
|
||||
}
|
||||
type LPWSADATA = *mut WSADATA;
|
||||
|
||||
#[link(name = "ws2_32")]
|
||||
extern "system" {
|
||||
fn WSAStartup(wVersionRequested: libc::WORD,
|
||||
lpWSAData: LPWSADATA) -> libc::c_int;
|
||||
}
|
||||
|
||||
unsafe {
|
||||
use std::unstable::mutex::{Mutex, MUTEX_INIT};
|
||||
static mut LOCK: Mutex = MUTEX_INIT;
|
||||
static mut INITIALIZED: bool = false;
|
||||
if INITIALIZED { return }
|
||||
LOCK.lock();
|
||||
if !INITIALIZED {
|
||||
let mut data: WSADATA = intrinsics::init();
|
||||
let ret = WSAStartup(0x202, // version 2.2
|
||||
&mut data);
|
||||
assert_eq!(ret, 0);
|
||||
INITIALIZED = true;
|
||||
}
|
||||
LOCK.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
impl TcpStream {
|
||||
pub fn connect(addr: ip::SocketAddr) -> IoResult<TcpStream> {
|
||||
unsafe {
|
||||
socket(addr).and_then(|fd| {
|
||||
let (addr, len) = addr_to_sockaddr(addr);
|
||||
let addrp = &addr as *libc::sockaddr_storage;
|
||||
let ret = TcpStream { fd: fd };
|
||||
match libc::connect(fd, addrp as *libc::sockaddr,
|
||||
len as libc::socklen_t) {
|
||||
-1 => Err(super::last_error()),
|
||||
_ => Ok(ret),
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub fn fd(&self) -> sock_t { self.fd }
|
||||
|
||||
fn set_nodelay(&mut self, nodelay: bool) -> IoResult<()> {
|
||||
unsafe {
|
||||
let on = nodelay as libc::c_int;
|
||||
let on = &on as *libc::c_int;
|
||||
super::mkerr_libc(libc::setsockopt(self.fd,
|
||||
libc::IPPROTO_TCP,
|
||||
libc::TCP_NODELAY,
|
||||
on as *libc::c_void,
|
||||
mem::size_of::<libc::c_void>()
|
||||
as libc::socklen_t))
|
||||
}
|
||||
}
|
||||
|
||||
fn set_keepalive(&mut self, seconds: Option<uint>) -> IoResult<()> {
|
||||
unsafe {
|
||||
let on = seconds.is_some() as libc::c_int;
|
||||
let on = &on as *libc::c_int;
|
||||
let ret = libc::setsockopt(self.fd,
|
||||
libc::SOL_SOCKET,
|
||||
libc::SO_KEEPALIVE,
|
||||
on as *libc::c_void,
|
||||
mem::size_of::<libc::c_void>()
|
||||
as libc::socklen_t);
|
||||
if ret != 0 { return Err(super::last_error()) }
|
||||
|
||||
match seconds {
|
||||
Some(n) => self.set_tcp_keepalive(n),
|
||||
None => Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
unsafe fn set_tcp_keepalive(&mut self, seconds: uint) -> IoResult<()> {
|
||||
let delay = seconds as libc::c_uint;
|
||||
let delay = &delay as *libc::c_uint;
|
||||
let ret = libc::setsockopt(self.fd,
|
||||
libc::IPPROTO_TCP,
|
||||
libc::TCP_KEEPALIVE,
|
||||
delay as *libc::c_void,
|
||||
mem::size_of::<libc::c_uint>()
|
||||
as libc::socklen_t);
|
||||
super::mkerr_libc(ret)
|
||||
}
|
||||
#[cfg(target_os = "freebsd")]
|
||||
unsafe fn set_tcp_keepalive(&mut self, seconds: uint) -> IoResult<()> {
|
||||
let delay = seconds as libc::c_uint;
|
||||
let delay = &delay as *libc::c_uint;
|
||||
let ret = libc::setsockopt(self.fd,
|
||||
libc::IPPROTO_TCP,
|
||||
libc::TCP_KEEPIDLE,
|
||||
delay as *libc::c_void,
|
||||
mem::size_of::<libc::c_uint>()
|
||||
as libc::socklen_t);
|
||||
super::mkerr_libc(ret)
|
||||
}
|
||||
#[cfg(not(target_os = "macos"), not(target_os = "freebsd"))]
|
||||
unsafe fn set_tcp_keepalive(&mut self, _seconds: uint) -> IoResult<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(windows)] type wrlen = libc::c_int;
|
||||
#[cfg(not(windows))] type wrlen = libc::size_t;
|
||||
|
||||
impl rtio::RtioTcpStream for TcpStream {
|
||||
fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
|
||||
let ret = keep_going(buf, |buf, len| {
|
||||
unsafe {
|
||||
libc::recv(self.fd,
|
||||
buf as *mut libc::c_void,
|
||||
len as wrlen,
|
||||
0) as i64
|
||||
}
|
||||
});
|
||||
if ret == 0 {
|
||||
Err(io::standard_error(io::EndOfFile))
|
||||
} else if ret < 0 {
|
||||
Err(super::last_error())
|
||||
} else {
|
||||
Ok(ret as uint)
|
||||
}
|
||||
}
|
||||
fn write(&mut self, buf: &[u8]) -> IoResult<()> {
|
||||
let ret = keep_going(buf, |buf, len| {
|
||||
unsafe {
|
||||
libc::send(self.fd,
|
||||
buf as *mut libc::c_void,
|
||||
len as wrlen,
|
||||
0) as i64
|
||||
}
|
||||
});
|
||||
if ret < 0 {
|
||||
Err(super::last_error())
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
fn peer_name(&mut self) -> IoResult<ip::SocketAddr> {
|
||||
sockname(self.fd, libc::getpeername)
|
||||
}
|
||||
fn control_congestion(&mut self) -> IoResult<()> {
|
||||
self.set_nodelay(false)
|
||||
}
|
||||
fn nodelay(&mut self) -> IoResult<()> {
|
||||
self.set_nodelay(true)
|
||||
}
|
||||
fn keepalive(&mut self, delay_in_seconds: uint) -> IoResult<()> {
|
||||
self.set_keepalive(Some(delay_in_seconds))
|
||||
}
|
||||
fn letdie(&mut self) -> IoResult<()> {
|
||||
self.set_keepalive(None)
|
||||
}
|
||||
}
|
||||
|
||||
impl rtio::RtioSocket for TcpStream {
|
||||
fn socket_name(&mut self) -> IoResult<ip::SocketAddr> {
|
||||
sockname(self.fd, libc::getsockname)
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for TcpStream {
|
||||
#[cfg(unix)]
|
||||
fn drop(&mut self) {
|
||||
unsafe { libc::close(self.fd); }
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn drop(&mut self) {
|
||||
unsafe { libc::closesocket(self.fd); }
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TcpListener {
|
||||
priv fd: sock_t,
|
||||
}
|
||||
|
||||
impl TcpListener {
|
||||
pub fn bind(addr: ip::SocketAddr) -> IoResult<TcpListener> {
|
||||
unsafe {
|
||||
socket(addr).and_then(|fd| {
|
||||
let (addr, len) = addr_to_sockaddr(addr);
|
||||
let addrp = &addr as *libc::sockaddr_storage;
|
||||
let ret = TcpListener { fd: fd };
|
||||
match libc::bind(fd, addrp as *libc::sockaddr,
|
||||
len as libc::socklen_t) {
|
||||
-1 => Err(super::last_error()),
|
||||
_ => Ok(ret),
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub fn fd(&self) -> sock_t { self.fd }
|
||||
|
||||
pub fn native_listen(self, backlog: int) -> IoResult<TcpAcceptor> {
|
||||
match unsafe { libc::listen(self.fd, backlog as libc::c_int) } {
|
||||
-1 => Err(super::last_error()),
|
||||
_ => Ok(TcpAcceptor { fd: self.fd })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl rtio::RtioTcpListener for TcpListener {
|
||||
fn listen(~self) -> IoResult<~rtio::RtioTcpAcceptor> {
|
||||
self.native_listen(128).map(|a| ~a as ~rtio::RtioTcpAcceptor)
|
||||
}
|
||||
}
|
||||
|
||||
impl rtio::RtioSocket for TcpListener {
|
||||
fn socket_name(&mut self) -> IoResult<ip::SocketAddr> {
|
||||
sockname(self.fd, libc::getsockname)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TcpAcceptor {
|
||||
priv fd: sock_t,
|
||||
}
|
||||
|
||||
impl TcpAcceptor {
|
||||
pub fn fd(&self) -> sock_t { self.fd }
|
||||
|
||||
pub fn native_accept(&mut self) -> IoResult<TcpStream> {
|
||||
unsafe {
|
||||
let mut storage: libc::sockaddr_storage = intrinsics::init();
|
||||
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;
|
||||
match libc::accept(self.fd,
|
||||
storagep as *mut libc::sockaddr,
|
||||
&mut size as *mut libc::socklen_t) {
|
||||
-1 => Err(super::last_error()),
|
||||
fd => Ok(TcpStream { fd: fd })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl rtio::RtioSocket for TcpAcceptor {
|
||||
fn socket_name(&mut self) -> IoResult<ip::SocketAddr> {
|
||||
sockname(self.fd, libc::getsockname)
|
||||
}
|
||||
}
|
||||
|
||||
impl rtio::RtioTcpAcceptor for TcpAcceptor {
|
||||
fn accept(&mut self) -> IoResult<~rtio::RtioTcpStream> {
|
||||
self.native_accept().map(|s| ~s as ~rtio::RtioTcpStream)
|
||||
}
|
||||
|
||||
fn accept_simultaneously(&mut self) -> IoResult<()> { Ok(()) }
|
||||
fn dont_accept_simultaneously(&mut self) -> IoResult<()> { Ok(()) }
|
||||
}
|
@ -407,8 +407,8 @@ fn spawn_process_os(prog: &str, args: &[~str],
|
||||
}
|
||||
|
||||
let pipe = os::pipe();
|
||||
let mut input = file::FileDesc::new(pipe.input, file::CloseFd);
|
||||
let mut output = file::FileDesc::new(pipe.out, file::CloseFd);
|
||||
let mut input = file::FileDesc::new(pipe.input, true);
|
||||
let mut output = file::FileDesc::new(pipe.out, true);
|
||||
|
||||
unsafe { set_cloexec(output.fd()) };
|
||||
|
||||
|
@ -34,6 +34,7 @@ pub fn new() -> ~Task {
|
||||
task.put_runtime(~Ops {
|
||||
lock: unsafe { Mutex::new() },
|
||||
awoken: false,
|
||||
io: io::IoFactory::new(),
|
||||
} as ~rt::Runtime);
|
||||
return task;
|
||||
}
|
||||
@ -86,8 +87,9 @@ pub fn spawn_opts(opts: TaskOpts, f: proc()) {
|
||||
// This structure is the glue between channels and the 1:1 scheduling mode. This
|
||||
// structure is allocated once per task.
|
||||
struct Ops {
|
||||
lock: Mutex, // native synchronization
|
||||
awoken: bool, // used to prevent spurious wakeups
|
||||
lock: Mutex, // native synchronization
|
||||
awoken: bool, // used to prevent spurious wakeups
|
||||
io: io::IoFactory, // local I/O factory
|
||||
}
|
||||
|
||||
impl rt::Runtime for Ops {
|
||||
@ -217,11 +219,7 @@ impl rt::Runtime for Ops {
|
||||
}
|
||||
|
||||
fn local_io<'a>(&'a mut self) -> Option<rtio::LocalIo<'a>> {
|
||||
static mut io: io::IoFactory = io::IoFactory;
|
||||
// Unsafety is from accessing `io`, which is guaranteed to be safe
|
||||
// because you can't do anything usable with this statically initialized
|
||||
// unit struct.
|
||||
Some(unsafe { rtio::LocalIo::new(&mut io as &mut rtio::IoFactory) })
|
||||
Some(rtio::LocalIo::new(&mut self.io as &mut rtio::IoFactory))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -345,6 +345,7 @@ pub fn uv_error_to_io_error(uverr: UvError) -> IoError {
|
||||
uvll::ENOENT => io::FileNotFound,
|
||||
uvll::EPIPE => io::BrokenPipe,
|
||||
uvll::ECONNABORTED => io::ConnectionAborted,
|
||||
uvll::EADDRNOTAVAIL => io::ConnectionRefused,
|
||||
err => {
|
||||
uvdebug!("uverr.code {}", err as int);
|
||||
// XXX: Need to map remaining uv error types
|
||||
|
@ -38,7 +38,7 @@ use std::libc;
|
||||
use std::libc::uintptr_t;
|
||||
|
||||
pub use self::errors::{EACCES, ECONNREFUSED, ECONNRESET, EPIPE, ECONNABORTED,
|
||||
ECANCELED, EBADF, ENOTCONN, ENOENT};
|
||||
ECANCELED, EBADF, ENOTCONN, ENOENT, EADDRNOTAVAIL};
|
||||
|
||||
pub static OK: c_int = 0;
|
||||
pub static EOF: c_int = -4095;
|
||||
@ -60,6 +60,7 @@ pub mod errors {
|
||||
pub static ECONNABORTED: c_int = -4079;
|
||||
pub static ECANCELED: c_int = -4081;
|
||||
pub static EBADF: c_int = -4083;
|
||||
pub static EADDRNOTAVAIL: c_int = -4090;
|
||||
}
|
||||
#[cfg(not(windows))]
|
||||
pub mod errors {
|
||||
@ -75,6 +76,7 @@ pub mod errors {
|
||||
pub static ECONNABORTED: c_int = -libc::ECONNABORTED;
|
||||
pub static ECANCELED : c_int = -libc::ECANCELED;
|
||||
pub static EBADF : c_int = -libc::EBADF;
|
||||
pub static EADDRNOTAVAIL : c_int = -libc::EADDRNOTAVAIL;
|
||||
}
|
||||
|
||||
pub static PROCESS_SETUID: c_int = 1 << 0;
|
||||
|
@ -138,8 +138,7 @@ mod test {
|
||||
use io::*;
|
||||
use prelude::*;
|
||||
|
||||
#[test] #[ignore]
|
||||
fn bind_error() {
|
||||
iotest!(fn bind_error() {
|
||||
let mut called = false;
|
||||
io_error::cond.trap(|e| {
|
||||
assert!(e.kind == PermissionDenied);
|
||||
@ -150,19 +149,12 @@ mod test {
|
||||
assert!(listener.is_none());
|
||||
});
|
||||
assert!(called);
|
||||
}
|
||||
} #[ignore(cfg(windows))])
|
||||
|
||||
#[test]
|
||||
fn connect_error() {
|
||||
iotest!(fn connect_error() {
|
||||
let mut called = false;
|
||||
io_error::cond.trap(|e| {
|
||||
let expected_error = if cfg!(unix) {
|
||||
ConnectionRefused
|
||||
} else {
|
||||
// On Win32, opening port 1 gives WSAEADDRNOTAVAIL error.
|
||||
OtherIoError
|
||||
};
|
||||
assert_eq!(e.kind, expected_error);
|
||||
assert_eq!(e.kind, ConnectionRefused);
|
||||
called = true;
|
||||
}).inside(|| {
|
||||
let addr = SocketAddr { ip: Ipv4Addr(0, 0, 0, 0), port: 1 };
|
||||
@ -170,10 +162,9 @@ mod test {
|
||||
assert!(stream.is_none());
|
||||
});
|
||||
assert!(called);
|
||||
}
|
||||
})
|
||||
|
||||
#[test]
|
||||
fn smoke_test_ip4() {
|
||||
iotest!(fn smoke_test_ip4() {
|
||||
let addr = next_test_ip4();
|
||||
let (port, chan) = Chan::new();
|
||||
|
||||
@ -189,10 +180,9 @@ mod test {
|
||||
let mut buf = [0];
|
||||
stream.read(buf);
|
||||
assert!(buf[0] == 99);
|
||||
}
|
||||
})
|
||||
|
||||
#[test]
|
||||
fn smoke_test_ip6() {
|
||||
iotest!(fn smoke_test_ip6() {
|
||||
let addr = next_test_ip6();
|
||||
let (port, chan) = Chan::new();
|
||||
|
||||
@ -208,10 +198,9 @@ mod test {
|
||||
let mut buf = [0];
|
||||
stream.read(buf);
|
||||
assert!(buf[0] == 99);
|
||||
}
|
||||
})
|
||||
|
||||
#[test]
|
||||
fn read_eof_ip4() {
|
||||
iotest!(fn read_eof_ip4() {
|
||||
let addr = next_test_ip4();
|
||||
let (port, chan) = Chan::new();
|
||||
|
||||
@ -227,10 +216,9 @@ mod test {
|
||||
let mut buf = [0];
|
||||
let nread = stream.read(buf);
|
||||
assert!(nread.is_none());
|
||||
}
|
||||
})
|
||||
|
||||
#[test]
|
||||
fn read_eof_ip6() {
|
||||
iotest!(fn read_eof_ip6() {
|
||||
let addr = next_test_ip6();
|
||||
let (port, chan) = Chan::new();
|
||||
|
||||
@ -246,10 +234,9 @@ mod test {
|
||||
let mut buf = [0];
|
||||
let nread = stream.read(buf);
|
||||
assert!(nread.is_none());
|
||||
}
|
||||
})
|
||||
|
||||
#[test]
|
||||
fn read_eof_twice_ip4() {
|
||||
iotest!(fn read_eof_twice_ip4() {
|
||||
let addr = next_test_ip4();
|
||||
let (port, chan) = Chan::new();
|
||||
|
||||
@ -275,10 +262,9 @@ mod test {
|
||||
let nread = stream.read(buf);
|
||||
assert!(nread.is_none());
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
#[test]
|
||||
fn read_eof_twice_ip6() {
|
||||
iotest!(fn read_eof_twice_ip6() {
|
||||
let addr = next_test_ip6();
|
||||
let (port, chan) = Chan::new();
|
||||
|
||||
@ -304,10 +290,9 @@ mod test {
|
||||
let nread = stream.read(buf);
|
||||
assert!(nread.is_none());
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
#[test]
|
||||
fn write_close_ip4() {
|
||||
iotest!(fn write_close_ip4() {
|
||||
let addr = next_test_ip4();
|
||||
let (port, chan) = Chan::new();
|
||||
|
||||
@ -336,10 +321,9 @@ mod test {
|
||||
});
|
||||
if stop { break }
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
#[test]
|
||||
fn write_close_ip6() {
|
||||
iotest!(fn write_close_ip6() {
|
||||
let addr = next_test_ip6();
|
||||
let (port, chan) = Chan::new();
|
||||
|
||||
@ -368,10 +352,9 @@ mod test {
|
||||
});
|
||||
if stop { break }
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
#[test]
|
||||
fn multiple_connect_serial_ip4() {
|
||||
iotest!(fn multiple_connect_serial_ip4() {
|
||||
let addr = next_test_ip4();
|
||||
let max = 10;
|
||||
let (port, chan) = Chan::new();
|
||||
@ -391,10 +374,9 @@ mod test {
|
||||
stream.read(buf);
|
||||
assert_eq!(buf[0], 99);
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
#[test]
|
||||
fn multiple_connect_serial_ip6() {
|
||||
iotest!(fn multiple_connect_serial_ip6() {
|
||||
let addr = next_test_ip6();
|
||||
let max = 10;
|
||||
let (port, chan) = Chan::new();
|
||||
@ -414,10 +396,9 @@ mod test {
|
||||
stream.read(buf);
|
||||
assert_eq!(buf[0], 99);
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
#[test]
|
||||
fn multiple_connect_interleaved_greedy_schedule_ip4() {
|
||||
iotest!(fn multiple_connect_interleaved_greedy_schedule_ip4() {
|
||||
let addr = next_test_ip4();
|
||||
static MAX: int = 10;
|
||||
let (port, chan) = Chan::new();
|
||||
@ -452,10 +433,9 @@ mod test {
|
||||
stream.write([i as u8]);
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
#[test]
|
||||
fn multiple_connect_interleaved_greedy_schedule_ip6() {
|
||||
iotest!(fn multiple_connect_interleaved_greedy_schedule_ip6() {
|
||||
let addr = next_test_ip6();
|
||||
static MAX: int = 10;
|
||||
let (port, chan) = Chan::<()>::new();
|
||||
@ -490,10 +470,9 @@ mod test {
|
||||
stream.write([i as u8]);
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
#[test]
|
||||
fn multiple_connect_interleaved_lazy_schedule_ip4() {
|
||||
iotest!(fn multiple_connect_interleaved_lazy_schedule_ip4() {
|
||||
let addr = next_test_ip4();
|
||||
static MAX: int = 10;
|
||||
let (port, chan) = Chan::new();
|
||||
@ -528,9 +507,9 @@ mod test {
|
||||
stream.write([99]);
|
||||
}
|
||||
}
|
||||
}
|
||||
#[test]
|
||||
fn multiple_connect_interleaved_lazy_schedule_ip6() {
|
||||
})
|
||||
|
||||
iotest!(fn multiple_connect_interleaved_lazy_schedule_ip6() {
|
||||
let addr = next_test_ip6();
|
||||
static MAX: int = 10;
|
||||
let (port, chan) = Chan::new();
|
||||
@ -565,10 +544,9 @@ mod test {
|
||||
stream.write([99]);
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
#[cfg(test)]
|
||||
fn socket_name(addr: SocketAddr) {
|
||||
pub fn socket_name(addr: SocketAddr) {
|
||||
let mut listener = TcpListener::bind(addr).unwrap();
|
||||
|
||||
// Make sure socket_name gives
|
||||
@ -578,8 +556,7 @@ mod test {
|
||||
assert_eq!(addr, so_name.unwrap());
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn peer_name(addr: SocketAddr) {
|
||||
pub fn peer_name(addr: SocketAddr) {
|
||||
let (port, chan) = Chan::new();
|
||||
|
||||
do spawn {
|
||||
@ -602,16 +579,14 @@ mod test {
|
||||
assert_eq!(addr, peer_name.unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn socket_and_peer_name_ip4() {
|
||||
iotest!(fn socket_and_peer_name_ip4() {
|
||||
peer_name(next_test_ip4());
|
||||
socket_name(next_test_ip4());
|
||||
}
|
||||
})
|
||||
|
||||
#[test]
|
||||
fn socket_and_peer_name_ip6() {
|
||||
iotest!(fn socket_and_peer_name_ip6() {
|
||||
// XXX: peer name is not consistent
|
||||
//peer_name(next_test_ip6());
|
||||
socket_name(next_test_ip6());
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ use std::io::net::ip::*;
|
||||
use sync::atomics::{AtomicUint, INIT_ATOMIC_UINT, Relaxed};
|
||||
|
||||
macro_rules! iotest (
|
||||
{ fn $name:ident() $b:block } => (
|
||||
{ fn $name:ident() $b:block $($a:attr)* } => (
|
||||
mod $name {
|
||||
#[allow(unused_imports)];
|
||||
|
||||
@ -28,6 +28,7 @@ macro_rules! iotest (
|
||||
use prelude::*;
|
||||
use io::*;
|
||||
use io::fs::*;
|
||||
use io::test::*;
|
||||
use io::net::tcp::*;
|
||||
use io::net::ip::*;
|
||||
use io::net::udp::*;
|
||||
@ -39,8 +40,8 @@ macro_rules! iotest (
|
||||
|
||||
fn f() $b
|
||||
|
||||
#[test] fn green() { f() }
|
||||
#[test] fn native() {
|
||||
$($a)* #[test] fn green() { f() }
|
||||
$($a)* #[test] fn native() {
|
||||
use native;
|
||||
let (p, c) = Chan::new();
|
||||
do native::task::spawn { c.send(f()) }
|
||||
@ -91,9 +92,9 @@ fn base_port() -> u16 {
|
||||
|
||||
let bases = [
|
||||
("32-opt", base + range * 1),
|
||||
("32-noopt", base + range * 2),
|
||||
("32-nopt", base + range * 2),
|
||||
("64-opt", base + range * 3),
|
||||
("64-noopt", base + range * 4),
|
||||
("64-nopt", base + range * 4),
|
||||
("64-opt-vg", base + range * 5),
|
||||
("all-opt", base + range * 6),
|
||||
("snap3", base + range * 7),
|
||||
|
@ -76,6 +76,7 @@ pub use libc::types::common::posix01::*;
|
||||
pub use libc::types::common::posix08::*;
|
||||
pub use libc::types::common::bsd44::*;
|
||||
pub use libc::types::os::common::posix01::*;
|
||||
pub use libc::types::os::common::bsd44::*;
|
||||
pub use libc::types::os::arch::c95::*;
|
||||
pub use libc::types::os::arch::c99::*;
|
||||
pub use libc::types::os::arch::posix88::*;
|
||||
@ -111,6 +112,7 @@ pub use libc::funcs::posix01::glob::*;
|
||||
pub use libc::funcs::posix01::mman::*;
|
||||
pub use libc::funcs::posix08::unistd::*;
|
||||
|
||||
pub use libc::funcs::bsd43::*;
|
||||
pub use libc::funcs::bsd44::*;
|
||||
pub use libc::funcs::extra::*;
|
||||
|
||||
@ -240,6 +242,40 @@ pub mod types {
|
||||
__unused5: *c_void,
|
||||
}
|
||||
}
|
||||
pub mod bsd44 {
|
||||
pub type socklen_t = u32;
|
||||
pub type sa_family_t = u16;
|
||||
pub type in_port_t = u16;
|
||||
pub type in_addr_t = u32;
|
||||
pub struct sockaddr {
|
||||
sa_family: sa_family_t,
|
||||
sa_data: [u8, ..14],
|
||||
}
|
||||
pub struct sockaddr_storage {
|
||||
ss_family: sa_family_t,
|
||||
__ss_align: i64,
|
||||
__ss_pad2: [u8, ..112],
|
||||
}
|
||||
pub struct sockaddr_in {
|
||||
sin_family: sa_family_t,
|
||||
sin_port: in_port_t,
|
||||
sin_addr: in_addr,
|
||||
sin_zero: [u8, ..8],
|
||||
}
|
||||
pub struct in_addr {
|
||||
s_addr: in_addr_t,
|
||||
}
|
||||
pub struct sockaddr_in6 {
|
||||
sin6_family: sa_family_t,
|
||||
sin6_port: in_port_t,
|
||||
sin6_flowinfo: u32,
|
||||
sin6_addr: in6_addr,
|
||||
sin6_scope_id: u32,
|
||||
}
|
||||
pub struct in6_addr {
|
||||
s6_addr: [u16, ..8]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "x86")]
|
||||
@ -538,6 +574,45 @@ pub mod types {
|
||||
__unused8: *c_void,
|
||||
}
|
||||
}
|
||||
pub mod bsd44 {
|
||||
pub type socklen_t = u32;
|
||||
pub type sa_family_t = u8;
|
||||
pub type in_port_t = u16;
|
||||
pub type in_addr_t = u32;
|
||||
pub struct sockaddr {
|
||||
sa_len: u8,
|
||||
sa_family: sa_family_t,
|
||||
sa_data: [u8, ..14],
|
||||
}
|
||||
pub struct sockaddr_storage {
|
||||
ss_len: u8,
|
||||
ss_family: sa_family_t,
|
||||
__ss_pad1: [u8, ..6],
|
||||
__ss_align: i64,
|
||||
__ss_pad2: [u8, ..112],
|
||||
}
|
||||
pub struct sockaddr_in {
|
||||
sin_len: u8,
|
||||
sin_family: sa_family_t,
|
||||
sin_port: in_port_t,
|
||||
sin_addr: in_addr,
|
||||
sin_zero: [u8, ..8],
|
||||
}
|
||||
pub struct in_addr {
|
||||
s_addr: in_addr_t,
|
||||
}
|
||||
pub struct sockaddr_in6 {
|
||||
sin6_len: u8,
|
||||
sin6_family: sa_family_t,
|
||||
sin6_port: in_port_t,
|
||||
sin6_flowinfo: u32,
|
||||
sin6_addr: in6_addr,
|
||||
sin6_scope_id: u32,
|
||||
}
|
||||
pub struct in6_addr {
|
||||
s6_addr: [u16, ..8]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
@ -661,6 +736,44 @@ pub mod types {
|
||||
modtime: time64_t,
|
||||
}
|
||||
}
|
||||
|
||||
pub mod bsd44 {
|
||||
use libc::types::os::arch::c95::{c_int, c_uint};
|
||||
|
||||
pub type SOCKET = c_uint;
|
||||
pub type socklen_t = c_int;
|
||||
pub type sa_family_t = u16;
|
||||
pub type in_port_t = u16;
|
||||
pub type in_addr_t = u32;
|
||||
pub struct sockaddr {
|
||||
sa_family: sa_family_t,
|
||||
sa_data: [u8, ..14],
|
||||
}
|
||||
pub struct sockaddr_storage {
|
||||
ss_family: sa_family_t,
|
||||
__ss_align: i64,
|
||||
__ss_pad2: [u8, ..112],
|
||||
}
|
||||
pub struct sockaddr_in {
|
||||
sin_family: sa_family_t,
|
||||
sin_port: in_port_t,
|
||||
sin_addr: in_addr,
|
||||
sin_zero: [u8, ..8],
|
||||
}
|
||||
pub struct in_addr {
|
||||
s_addr: in_addr_t,
|
||||
}
|
||||
pub struct sockaddr_in6 {
|
||||
sin6_family: sa_family_t,
|
||||
sin6_port: in_port_t,
|
||||
sin6_flowinfo: u32,
|
||||
sin6_addr: in6_addr,
|
||||
sin6_scope_id: u32,
|
||||
}
|
||||
pub struct in6_addr {
|
||||
s6_addr: [u16, ..8]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub mod arch {
|
||||
@ -900,6 +1013,48 @@ pub mod types {
|
||||
__unused8: *c_void,
|
||||
}
|
||||
}
|
||||
|
||||
pub mod bsd44 {
|
||||
use libc::types::os::arch::c95::c_int;
|
||||
|
||||
pub type socklen_t = c_int;
|
||||
pub type sa_family_t = u8;
|
||||
pub type in_port_t = u16;
|
||||
pub type in_addr_t = u32;
|
||||
pub struct sockaddr {
|
||||
sa_len: u8,
|
||||
sa_family: sa_family_t,
|
||||
sa_data: [u8, ..14],
|
||||
}
|
||||
pub struct sockaddr_storage {
|
||||
ss_len: u8,
|
||||
ss_family: sa_family_t,
|
||||
__ss_pad1: [u8, ..6],
|
||||
__ss_align: i64,
|
||||
__ss_pad2: [u8, ..112],
|
||||
}
|
||||
pub struct sockaddr_in {
|
||||
sin_len: u8,
|
||||
sin_family: sa_family_t,
|
||||
sin_port: in_port_t,
|
||||
sin_addr: in_addr,
|
||||
sin_zero: [u8, ..8],
|
||||
}
|
||||
pub struct in_addr {
|
||||
s_addr: in_addr_t,
|
||||
}
|
||||
pub struct sockaddr_in6 {
|
||||
sin6_len: u8,
|
||||
sin6_family: sa_family_t,
|
||||
sin6_port: in_port_t,
|
||||
sin6_flowinfo: u32,
|
||||
sin6_addr: in6_addr,
|
||||
sin6_scope_id: u32,
|
||||
}
|
||||
pub struct in6_addr {
|
||||
s6_addr: [u16, ..8]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "x86")]
|
||||
@ -1109,6 +1264,59 @@ pub mod consts {
|
||||
pub static FILENAME_MAX : c_uint = 260_u32;
|
||||
pub static L_tmpnam : c_uint = 16_u32;
|
||||
pub static TMP_MAX : c_uint = 32767_u32;
|
||||
|
||||
pub static WSAEINTR: c_int = 10004;
|
||||
pub static WSAEBADF: c_int = 10009;
|
||||
pub static WSAEACCES: c_int = 10013;
|
||||
pub static WSAEFAULT: c_int = 10014;
|
||||
pub static WSAEINVAL: c_int = 10022;
|
||||
pub static WSAEMFILE: c_int = 10024;
|
||||
pub static WSAEWOULDBLOCK: c_int = 10035;
|
||||
pub static WSAEINPROGRESS: c_int = 10036;
|
||||
pub static WSAEALREADY: c_int = 10037;
|
||||
pub static WSAENOTSOCK: c_int = 10038;
|
||||
pub static WSAEDESTADDRREQ: c_int = 10039;
|
||||
pub static WSAEMSGSIZE: c_int = 10040;
|
||||
pub static WSAEPROTOTYPE: c_int = 10041;
|
||||
pub static WSAENOPROTOOPT: c_int = 10042;
|
||||
pub static WSAEPROTONOSUPPORT: c_int = 10043;
|
||||
pub static WSAESOCKTNOSUPPORT: c_int = 10044;
|
||||
pub static WSAEOPNOTSUPP: c_int = 10045;
|
||||
pub static WSAEPFNOSUPPORT: c_int = 10046;
|
||||
pub static WSAEAFNOSUPPORT: c_int = 10047;
|
||||
pub static WSAEADDRINUSE: c_int = 10048;
|
||||
pub static WSAEADDRNOTAVAIL: c_int = 10049;
|
||||
pub static WSAENETDOWN: c_int = 10050;
|
||||
pub static WSAENETUNREACH: c_int = 10051;
|
||||
pub static WSAENETRESET: c_int = 10052;
|
||||
pub static WSAECONNABORTED: c_int = 10053;
|
||||
pub static WSAECONNRESET: c_int = 10054;
|
||||
pub static WSAENOBUFS: c_int = 10055;
|
||||
pub static WSAEISCONN: c_int = 10056;
|
||||
pub static WSAENOTCONN: c_int = 10057;
|
||||
pub static WSAESHUTDOWN: c_int = 10058;
|
||||
pub static WSAETOOMANYREFS: c_int = 10059;
|
||||
pub static WSAETIMEDOUT: c_int = 10060;
|
||||
pub static WSAECONNREFUSED: c_int = 10061;
|
||||
pub static WSAELOOP: c_int = 10062;
|
||||
pub static WSAENAMETOOLONG: c_int = 10063;
|
||||
pub static WSAEHOSTDOWN: c_int = 10064;
|
||||
pub static WSAEHOSTUNREACH: c_int = 10065;
|
||||
pub static WSAENOTEMPTY: c_int = 10066;
|
||||
pub static WSAEPROCLIM: c_int = 10067;
|
||||
pub static WSAEUSERS: c_int = 10068;
|
||||
pub static WSAEDQUOT: c_int = 10069;
|
||||
pub static WSAESTALE: c_int = 10070;
|
||||
pub static WSAEREMOTE: c_int = 10071;
|
||||
pub static WSASYSNOTREADY: c_int = 10091;
|
||||
pub static WSAVERNOTSUPPORTED: c_int = 10092;
|
||||
pub static WSANOTINITIALISED: c_int = 10093;
|
||||
pub static WSAEDISCON: c_int = 10101;
|
||||
pub static WSAENOMORE: c_int = 10102;
|
||||
pub static WSAECANCELLED: c_int = 10103;
|
||||
pub static WSAEINVALIDPROCTABLE: c_int = 10104;
|
||||
pub static WSAEINVALIDPROVIDER: c_int = 10105;
|
||||
pub static WSAEPROVIDERFAILEDINIT: c_int = 10106;
|
||||
}
|
||||
pub mod c99 {
|
||||
}
|
||||
@ -1149,6 +1357,17 @@ pub mod consts {
|
||||
pub mod posix08 {
|
||||
}
|
||||
pub mod bsd44 {
|
||||
use libc::types::os::arch::c95::c_int;
|
||||
|
||||
pub static AF_INET: c_int = 2;
|
||||
pub static AF_INET6: c_int = 23;
|
||||
pub static SOCK_STREAM: c_int = 1;
|
||||
pub static SOCK_DGRAM: c_int = 2;
|
||||
pub static IPPROTO_TCP: c_int = 6;
|
||||
|
||||
pub static TCP_NODELAY: c_int = 0x0001;
|
||||
pub static SOL_SOCKET: c_int = 0xffff;
|
||||
pub static SO_KEEPALIVE: c_int = 8;
|
||||
}
|
||||
pub mod extra {
|
||||
use libc::types::os::arch::c95::c_int;
|
||||
@ -1845,6 +2064,16 @@ pub mod consts {
|
||||
pub static MADV_MERGEABLE : c_int = 12;
|
||||
pub static MADV_UNMERGEABLE : c_int = 13;
|
||||
pub static MADV_HWPOISON : c_int = 100;
|
||||
|
||||
pub static AF_INET: c_int = 2;
|
||||
pub static AF_INET6: c_int = 10;
|
||||
pub static SOCK_STREAM: c_int = 1;
|
||||
pub static SOCK_DGRAM: c_int = 2;
|
||||
pub static IPPROTO_TCP: c_int = 6;
|
||||
|
||||
pub static TCP_NODELAY: c_int = 1;
|
||||
pub static SOL_SOCKET: c_int = 1;
|
||||
pub static SO_KEEPALIVE: c_int = 9;
|
||||
}
|
||||
#[cfg(target_arch = "x86")]
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
@ -2262,6 +2491,17 @@ pub mod consts {
|
||||
pub static MINCORE_REFERENCED_OTHER : c_int = 0x8;
|
||||
pub static MINCORE_MODIFIED_OTHER : c_int = 0x10;
|
||||
pub static MINCORE_SUPER : c_int = 0x20;
|
||||
|
||||
pub static AF_INET: c_int = 2;
|
||||
pub static AF_INET6: c_int = 28;
|
||||
pub static SOCK_STREAM: c_int = 1;
|
||||
pub static SOCK_DGRAM: c_int = 2;
|
||||
pub static IPPROTO_TCP: c_int = 6;
|
||||
|
||||
pub static TCP_NODELAY: c_int = 1;
|
||||
pub static TCP_KEEPIDLE: c_int = 256;
|
||||
pub static SOL_SOCKET: c_int = 0xffff;
|
||||
pub static SO_KEEPALIVE: c_int = 0x0008;
|
||||
}
|
||||
pub mod extra {
|
||||
use libc::types::os::arch::c95::c_int;
|
||||
@ -2616,6 +2856,17 @@ pub mod consts {
|
||||
pub static MINCORE_MODIFIED : c_int = 0x4;
|
||||
pub static MINCORE_REFERENCED_OTHER : c_int = 0x8;
|
||||
pub static MINCORE_MODIFIED_OTHER : c_int = 0x10;
|
||||
|
||||
pub static AF_INET: c_int = 2;
|
||||
pub static AF_INET6: c_int = 30;
|
||||
pub static SOCK_STREAM: c_int = 1;
|
||||
pub static SOCK_DGRAM: c_int = 2;
|
||||
pub static IPPROTO_TCP: c_int = 6;
|
||||
|
||||
pub static TCP_NODELAY: c_int = 0x01;
|
||||
pub static TCP_KEEPALIVE: c_int = 0x10;
|
||||
pub static SOL_SOCKET: c_int = 0xffff;
|
||||
pub static SO_KEEPALIVE: c_int = 0x0008;
|
||||
}
|
||||
pub mod extra {
|
||||
use libc::types::os::arch::c95::c_int;
|
||||
@ -3296,6 +3547,63 @@ pub mod funcs {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
pub mod bsd43 {
|
||||
use libc::types::common::c95::{c_void};
|
||||
use libc::types::os::common::bsd44::{socklen_t, sockaddr};
|
||||
use libc::types::os::arch::c95::{c_int, size_t};
|
||||
use libc::types::os::arch::posix88::ssize_t;
|
||||
|
||||
extern "system" {
|
||||
pub fn socket(domain: c_int, ty: c_int, protocol: c_int) -> c_int;
|
||||
pub fn connect(socket: c_int, address: *sockaddr,
|
||||
len: socklen_t) -> c_int;
|
||||
pub fn bind(socket: c_int, address: *sockaddr,
|
||||
address_len: socklen_t) -> c_int;
|
||||
pub fn listen(socket: c_int, backlog: c_int) -> c_int;
|
||||
pub fn accept(socket: c_int, address: *mut sockaddr,
|
||||
address_len: *mut socklen_t) -> c_int;
|
||||
pub fn getpeername(socket: c_int, address: *mut sockaddr,
|
||||
address_len: *mut socklen_t) -> c_int;
|
||||
pub fn getsockname(socket: c_int, address: *mut sockaddr,
|
||||
address_len: *mut socklen_t) -> c_int;
|
||||
pub fn setsockopt(socket: c_int, level: c_int, name: c_int,
|
||||
value: *c_void, option_len: socklen_t) -> c_int;
|
||||
pub fn recv(socket: c_int, buf: *mut c_void, len: size_t,
|
||||
flags: c_int) -> ssize_t;
|
||||
pub fn send(socket: c_int, buf: *mut c_void, len: size_t,
|
||||
flags: c_int) -> ssize_t;
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
pub mod bsd43 {
|
||||
use libc::types::common::c95::{c_void};
|
||||
use libc::types::os::common::bsd44::{socklen_t, sockaddr, SOCKET};
|
||||
use libc::types::os::arch::c95::c_int;
|
||||
|
||||
extern "system" {
|
||||
pub fn socket(domain: c_int, ty: c_int, protocol: c_int) -> SOCKET;
|
||||
pub fn connect(socket: SOCKET, address: *sockaddr,
|
||||
len: socklen_t) -> c_int;
|
||||
pub fn bind(socket: SOCKET, address: *sockaddr,
|
||||
address_len: socklen_t) -> c_int;
|
||||
pub fn listen(socket: SOCKET, backlog: c_int) -> c_int;
|
||||
pub fn accept(socket: SOCKET, address: *mut sockaddr,
|
||||
address_len: *mut socklen_t) -> SOCKET;
|
||||
pub fn getpeername(socket: SOCKET, address: *mut sockaddr,
|
||||
address_len: *mut socklen_t) -> c_int;
|
||||
pub fn getsockname(socket: SOCKET, address: *mut sockaddr,
|
||||
address_len: *mut socklen_t) -> c_int;
|
||||
pub fn setsockopt(socket: SOCKET, level: c_int, name: c_int,
|
||||
value: *c_void, option_len: socklen_t) -> c_int;
|
||||
pub fn closesocket(socket: SOCKET) -> c_int;
|
||||
pub fn recv(socket: SOCKET, buf: *mut c_void, len: c_int,
|
||||
flags: c_int) -> c_int;
|
||||
pub fn send(socket: SOCKET, buf: *mut c_void, len: c_int,
|
||||
flags: c_int) -> c_int;
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
#[cfg(target_os = "freebsd")]
|
||||
|
Loading…
Reference in New Issue
Block a user